此查询需要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`
我所做的只是从子句中删除一个项目。我可以删除任何一个项目。只要有9个或更少的项目,它就会在4秒内运行。一旦我增加10个项目,就需要18秒钟才能运行。
我认为mysql有限的命令长度,即1MB
不仅仅是EXPLAIN
,还要使用EXPLAIN FORMAT=JSON
并获取查询的"优化器跟踪"。我怀疑IN
的长度会导致选择其他查询计划。
IN
中的项目数几乎没有限制。我看到了多达70k。
除此之外,您甚至可以加快4-SEC版本...
我建议有此索引。grrr ...我无法分辨哪个列在哪个表。因此,如果所有这些都在一个表中,则进行这样的索引:
INDEX(production_type, contract, project) -- in any order
如果所有这些都在wd
中,则在第四列上钉 - week
,itemgroup
,days
。
对COUNT(wd.hold_code)
谨慎。
-
COUNT(x)
检查x
是否为非NULL
;那是你要的吗?如果没有,请简单地说COUNT(*)
。 - 当
JOINing
,然后是GROUP BY
时,您将获得"爆炸implode"。中间行的数量很大;那是执行COUNT
的时候。 -
COUNT(hold_code)
和GROUP BY hold_code
似乎都是错误的。你想做什么?
要进行进一步的讨论,请提供SHOW CREATE TABLE
和EXPLAIN
。
请注意,在Max_allowed_packet值中建立了子句限制中的MySQL。如果结果更快,您可以不检查。另外,我建议将值在缓冲区字符串而不是逗号分隔值的子句中进行检查,然后尝试一下。