mysql in子句速度慢,包含10项或更多项

3zwjbxry  于 2021-06-24  发布在  Mysql
关注(0)|答案(2)|浏览(363)

此查询需要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

zbsbpyhn

zbsbpyhn1#

请注意,mysql in子句限制是用最大允许的数据包值建立的。如果结果更快,您可以与not in联系。另外,我建议在缓冲区字符串下放置要用in子句检查的值,而不是用逗号分隔的值,然后再试一次。

bwleehnv

bwleehnv2#

不仅仅是 EXPLAIN ,使用 EXPLAIN FORMAT=JSON 并获取查询的“优化器跟踪”。我怀疑 IN 导致选择不同的查询计划。
几乎没有限制的项目数量 IN . 我见过多达7万人。
除此之外,你甚至可以加速4秒版本。。。
我建议用这个索引。格瑞。。。我不知道哪些列在哪些表中。因此,如果这些都在一个表中,那么创建这样一个索引:

INDEX(production_type, contract, project) -- in any order

如果这些都在 wd ,然后在第四栏钉上一个 week , itemgroup , days .
谨慎对待 COUNT(wd.hold_code) . COUNT(x) 检查 x 因为你不是- NULL ; 这就是你想要的吗?如果没有,那就简单地说 COUNT(*) .
什么时候 JOINing ,那么 GROUP BY ,你会得到一个“爆炸-内爆”。中间行数较多;就在那时 COUNT 已执行。
对双方来说似乎都不对 COUNT(hold_code) 以及 GROUP BY hold_code . 你想干什么?
为进一步讨论,请提供 SHOW CREATE TABLE 以及 EXPLAIN .

相关问题