【问题标题】:How to execute query on a large database without exists如何在不存在的大型数据库上执行查询
【发布时间】:2014-02-19 11:50:25
【问题描述】:

MYSQL 5.1.52-社区 我有一张有 250 万行的大桌子:

我写了这个查询来解析数据:

SELECT dem.iddem,
       rrbc.p0012 AS libdemandeur,
       rrbp.p0012 AS libaffectation,
       dem.regate,
       dem.bp,
       dem.typeabsence,
       dem.datedeb,
       dem.datefin
FROM   demandes dem
       LEFT OUTER JOIN regate_regate rrbp
                    ON rrbp.p0016 = '038'
                       AND dem.bp = rrbp.regate
       LEFT OUTER JOIN regate_regate rrbc
                    ON ( rrbc.p0016 = '038'
                         AND dem.regate = rrbc.regate )
       INNER JOIN planning_demandes pd
               ON dem.iddem = pd.id_dem
WHERE  1
       AND EXISTS(SELECT 1
                  FROM   planning_demandes b
                  WHERE  pd.id_dem = b.id_dem
                         AND idrh IS NOT NULL
                         AND idrh <> 'férié'
                         AND idrh <> 'Pferié')
       AND EXISTS(SELECT 1
                  FROM   planning_demandes c
                  WHERE  pd.id_dem = c.id_dem
                         AND idrh IS NULL)
       AND dem.etat NOT IN ( '0', '1', '2', '7', '8' )
GROUP  BY iddem
ORDER  BY dem.datedeb ASC

我想知道是否有人想快速加载此请求:

也许子查询在大表上是一个非常糟糕的主意? 我创建了这个索引:create index IDX_DEM_IDRH on planning_demandes(id_dem, idrh);

EXPLAIN

INDEX OF PLANNING_DEMANDES AND DEMANDES

【问题讨论】:

  • 哪些表有250万行?其他表的体积是多少?我会称 250 万行为“中等” - 取决于列数
  • 查询执行:91.8204 秒表需求:149267 行表计划需求:2545088 行表 regate_regate:20650 行
  • 与您的问题无关,但信息“MySQL 5”并不是非常有用。有 5.0、5.1、5.5、5.6、5.7(以及每个版本的各种补丁版本 - 每个补丁版本都有不同的功能和特性)
  • 是的,对不起它的 MYSQL 5.1.52-community
  • 您的EXISTS 子句可能会合并(条件似乎是OR-able)。请注意,如果regate_regate 中有多行具有匹配条件,则p0012 中的结果值是未定义的(由于GROUP BY 没有聚合) - 这是假设demandes.idem 是唯一的开始(你需要GROUP BY 吗?)。我个人不喜欢这个“功能”。

标签: mysql sql optimization join subquery


【解决方案1】:

请检查此查询的解释计划并验证它是否使用索引 IDX_DEM_IDRH。还要检查哪个连接花费的时间最长。

语法:

explain plan for <your select query>;
select * from table(dbms_xplan);

我认为您应该在planning_demandes.id_dem 和planning_demandes.idrh 上有单独的索引。还要考虑对 demandes.iddem 的索引。

【讨论】:

  • 你看对了吗?我的解释有什么问题吗?
  • 好吧,我是 Oracle 人..(很抱歉错过了 MySQL 标签)无论如何.. 看看计划,很明显查询的瓶颈是“需求”的全表扫描
  • 对不起,我不明白。以另一种方式,我不应该通过 join 替换子查询吗?
  • yr 子查询似乎没问题.. 正如您在解释计划中看到的那样,相关查询运行良好,它们使用索引并有效地执行 5 和 8 行搜索
  • 是的,但是表“要求”有 100k 行搜索我应该创建临时表还是?
猜你喜欢
  • 2019-02-28
  • 1970-01-01
  • 2016-09-23
  • 2015-07-09
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多