【发布时间】:2018-10-05 15:47:49
【问题描述】:
这个查询需要 18 秒
SELECT `wd`.`week` AS `start_week`, `wd`.`hold_code`, COUNT(wd.hold_code) AS hold_code_count
FROM `weekly_data` AS `wd`
JOIN aol_reporting_hold_codes hc ON hc.hold_code = wd.hold_code AND chart = 'GR'
WHERE `wd`.`days` <= 6
AND `wd`.`hold_code` IS NOT NULL
AND NOT `wd`.`hold_code` = ''
AND `wd`.`week` >= '201717'
AND `wd`.`itemgroup` IN ('BOTDTO', 'BOTDWG', 'C&FORG', 'C&FOTO', 'MF-SUB', 'MI-SUB', 'PROPRI', 'PROPTO', 'STRSTO', 'STRSUB')
AND `production_type` = 2
AND `contract` = "1234"
AND `project` = 8
GROUP BY `start_week`, `wd`.`hold_code`
此查询需要 4 秒
SELECT `wd`.`week` AS `start_week`, `wd`.`hold_code`, COUNT(wd.hold_code) AS hold_code_count
FROM `weekly_data` AS `wd`
JOIN aol_reporting_hold_codes hc ON hc.hold_code = wd.hold_code AND chart = 'GR'
WHERE `wd`.`days` <= 6
AND `wd`.`hold_code` IS NOT NULL
AND NOT `wd`.`hold_code` = ''
AND `wd`.`week` >= '201717'
AND `wd`.`itemgroup` IN ('BOTDWG', 'C&FORG', 'C&FOTO', 'MF-SUB', 'MI-SUB', 'PROPRI', 'PROPTO', 'STRSTO', 'STRSUB')
AND `production_type` = 2
AND `contract` = "1234"
AND `project` = 8
GROUP BY `start_week`, `wd`.`hold_code`
我所做的只是从 IN 子句中删除了一项。我可以删除任何一项。只要有 9 个或更少的项目,它就会在 4 秒内运行。我增加到 10 个项目需要 18 秒才能运行。
我认为 MySQL 按大小限制命令长度,即 1MB
【问题讨论】:
-
你检查执行计划了吗?
-
我们需要知道执行计划(知道索引也会有所帮助)。稍微改变查询很可能会导致不同的执行计划。不过,我的猜测是您在
weekly_data.itemgroup上缺少索引,但为什么需要这么长时间取决于用于搜索条件的其他列上的数据和索引。 -
@MattGibson 谢谢,我刚刚运行解释,发现在我的 IN 子句中使用 9 选项时,使用的键是“contract,project__idx,production_type” 当我添加第十个键时,键就是 itemgroup。不确定解决方案是什么,我确实已经在 itemgroup 上有了一个密钥。除非有其他更好的建议,否则我可能会删除并重新添加它。
-
我不会删除并重新添加索引。你需要弄清楚为什么优化器猜错了;可能是统计数据需要刷新,或者您最好添加另一个更合适的索引,但该索引是什么取决于您的数据。
-
(在此阶段要考虑的一件事:
WHERE子句的哪些单独部分会最大程度地缩小结果?即,您的哪个比较从潜在的完整中过滤掉了最多的行数结果集?你有合适的索引吗?例如,如果你在week上没有索引,但你的表中有十年的数据,那么你可能关注的是错误的问题:D )
标签: mysql sql performance in-clause