[英]UPDATE with SELECT subquery runs extremely slowly on MySQL 5.7 (but was fine on 5.5)
谢谢大家。 我将数据库从MySQL 5.5升级到5.7时遇到了一个问题,使我完全感到困惑。 升级不是使用mysqldump或类似工具完成的,而是使用几个很长的SQL脚本从几个制表符分隔的输入文件中重建的。 特别是(在存储过程中)一个看似无害的查询给我带来麻烦,但我无法弄清原因:
UPDATE liverpool.master_person mp
SET Link_Count = ( SELECT count(*) FROM liverpool.person_record pr
WHERE mp.Master_Person_ID = pr.Master_Person_ID ) - 1;
这似乎相当简单,但是此查询的EXPLAIN显示正在进行一些认真的行扫描:
# id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
========================================================================================================================================================================
'1' | 'UPDATE' | 'mp' | NULL | 'index' | NULL | 'PRIMARY' | '4' | NULL | '1198100' | '100.00' | NULL
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'2' | 'DEPENDENT SUBQUERY' | 'pr' | NULL | 'index' | NULL | 'Master_Person_ID_IDX' | '17' | NULL | '1200537' | '100.00' | 'Using where; Using index'
重要的事情似乎是rows列,对于UPDATE来说是1198100,对于SELECT子查询来说是1200537。 这两个数字都非常接近两个引用表中的行总数(两个表均为1207744)。 因此,似乎对这两者都进行了整行的行扫描,我不知道为什么。 确切地说,相同的查询在MySQL 5.5中可以正常工作。 我希望该解决方案会有所帮助,但是将'derived_merge = off'传递给了optimizer_switch,重新启动服务器没有帮助。
我当然不希望这个查询超级快。 不一定是。 之前速度并不很快(在7200rpm的旋转磁盘上几分钟),但是由于升级到MySQL 5.7,似乎在宇宙热死之前的任何时候都无法完成,所以我宁愿不要等待长。 有没有人有任何想法? 查询重写还是my.ini设置或其他所有内容?
另外,请告知我是否以任何方式违反了协议或可以改善我的问题。 正如我上面所说,这是我在这里的第一篇文章。
感谢您的时间。
编辑:我想了一下, 这种解决方案看起来很有希望。 显然,具有不同字符集/排序规则的表无法正确读取彼此的索引。 我非常确定所有内容都在latin1
,但认为值得确定。 因此,我将DEFAULT CHARSET=latin1
明确添加到所有CREATE TABLE
语句中,并将CHARACTER SET latin1
添加到我的LOAD DATA INFILE
语句中。 可悲的是,没有变化。
尝试将查询重写为:
UPDATE liverpool.master_person mp
JOIN (SELECT Master_Person_ID, count(*) as cnt
FROM liverpool.person_record
GROUP BY Master_Person_ID)
) pr
ON mp.Master_Person_ID = pr.Master_Person_ID
SET mp.Link_Count = pr.cnt - 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.