繁体   English   中英

使用SELECT子查询的UPDATE在MySQL 5.7上运行非常慢(但在5.5上很好)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM