【问题标题】:Slow updates with MySQL innoDB (clueless)MySQL innoDB 更新缓慢(无能)
【发布时间】:2012-02-20 09:29:38
【问题描述】:

我有一个相当简单的查询,大多数运行速度非常快,而在其他极少数情况下最多需要 30 秒。我不知道是什么原因造成的。这是我所说的一个例子。

mysql> UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS != 'N' 设置 msm.STATUS = 'P' 其中 msm.memberNo = 7 AND msm.STATUS = 'M';
查询正常,0 行受影响(0.00 秒)
匹配行:0 更改:0 警告:0

mysql> UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS != 'N' 设置 msm.STATUS = 'P' 其中 msm.memberNo = 7 AND msm.STATUS = 'M';
查询正常,0 行受影响(0.00 秒)
匹配行:0 更改:0 警告:0

mysql> UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS != 'N' SET msm.STATUS = 'P' 其中 msm.memberNo = 7 AND msm.STATUS = 'M';
查询正常,0 行受影响(3.01 秒)
匹配行:0 更改:0 警告:0

mysql> UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS != 'N' 设置 msm.STATUS = 'P' 其中 msm.memberNo = 7 AND msm.STATUS = 'M';
查询正常,0 行受影响(0.00 秒)
匹配行:0 更改:0 警告:0

mysql> UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS != 'N' SET msm.STATUS = 'P' 其中 msm.memberNo = 7 AND msm.STATUS = 'M';
查询正常,0 行受影响(1.88 秒)
匹配行:0 更改:0 警告:0

mysql> UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS != 'N' 设置 msm.STATUS = 'P' 其中 msm.memberNo = 7 AND msm.STATUS = 'M';
查询正常,0 行受影响(0.00 秒)
匹配行:0 更改:0 警告:0

在这个查询中,我为所有 msm.matchNo、ms.matchNo、ms.status、msm.status 和 msm.memberNo 设置了索引。

我运行相同的查询 6 次,有 4 个案例的查询在一秒钟内完成,而 2 个案例的处理时间超过一秒。我进行了更多测试,并获得了其中一个更严重的案例的配置文件数据,执行这个愚蠢的查询最多需要 30 秒。

mysql> SHOW PROFILE FOR QUERY 3;  
+---------------------------+-----------+  
| Status                    | Duration  |  
+---------------------------+-----------+  
| starting                  |  0.000075 |  
| checking permissions      |  0.000013 |  
| checking permissions      |  0.000012 |  
| Opening tables            |  0.000073 |  
| checking permissions      |  0.000011 |  
| checking permissions      |  0.000013 |  
| System lock               |  0.000023 |  
| init                      |  0.000021 |  
| updating main table       |  0.000014 |  
| optimizing                |  0.000020 |  
| statistics                |  0.000117 |  
| preparing                 |  0.000028 |  
| executing                 |  0.000011 |  
| Sending data              | 31.940094 | <==
| updating reference tables |  0.000039 |  
| end                       |  0.000016 |  
| end                       |  0.000015 |  
| query end                 |  0.000048 |  
| closing tables            |  0.000039 |  
| freeing items             |  0.000036 |  
| logging slow query        |  0.000011 |  
| cleaning up               |  0.000014 |  
+---------------------------+-----------+  

我还有其他一些具有类似症状的 UPDATE 查询。即使实际上没有任何行被更新,为什么这个查询需要这么长时间才能执行?这个“发送数据”的瓶颈可能是什么?

** 编辑:为正在使用的两个表添加了 CREATE TABLE 代码

创建表 matchSessionMembers (
matchNo int(11) NOT NULL,
memberNo int(11) NOT NULL,
status char(1) NOT NULL DEFAULT 'M ' COMMENT 'M=匹配,P=待定,Y=saidYes,N=saidNo,D=deleted',
muted char(1) NOT NULL DEFAULT 'N',
deleted char(1 ) NOT NULL DEFAULT 'N',
regDatetime datetime DEFAULT NULL,
exitDatetime datetime DEFAULT NULL,
主键 (matchNo,memberNo),
status (status),
FK_matchSessionMembers_memberNo (memberNo),
regDatetime (regDatetime),
FK_matchSessionMembers_matchNo (matchNo),
约束 FK_matchSessionMembers_matchNo 外键 (matchNo) 参考 matchSessions (matchNo),
约束 FK_matchSessionMembers_memberNo 外键 (memberNo) 参考 members (memberNo)
) ENGINE=InnoDB 默认字符集=utf8

创建表 matchSessions (
matchNo int(11) NOT NULL AUTO_INCREMENT,
memberCount int(11) NOT NULL,
status char(1) NOT NULL DEFAULT ' P' COMMENT 'P=待处理,Y=成功,N=不成功,X=过期',
isQuickMatch char(1) NOT NULL DEFAULT 'N',
open char(1) NOT NULL默认'N',
regDatetime datetime 默认空,
activeDate date 默认空,
expireDate date 默认空,
主键 (matchNo),
status (status),
activeDate (activeDate),
expireDate (expireDate)
) ENGINE=InnoDB AUTO_INCREMENT=113912 默认字符集=utf8

【问题讨论】:

  • 我们在谈论多少行?我的意思是这两个表中的大约行数。
  • 请尝试UPDATE matchSessionMembers msm JOIN matchSessions ms ON msm.matchNo = ms.matchNo SET msm.STATUS = 'P' WHERE msm.memberNo = 7 AND msm.STATUS = 'M' AND ms.STATUS != 'N'; 并报告。
  • 数量并不可怕。 matchSessions 大约 110k,matchSessionMembers 大约 220k。
  • 发送数据瓶颈实际上是在那之前的一步。这是一个带有查询分析的已知问题。所以执行是造成瓶颈的原因,这很可能是由于必须检查的行数。
  • @N.B.我已经想到了,但我不明白为什么查询时间如此明显不一致。

标签: mysql sql innodb


【解决方案1】:

我想通了。

我犯了一个愚蠢的错误。不过,这并不容易识别。 我有一个不同的超慢查询,每隔一小时左右运行一次,一个更新查询需要 30 多秒才能执行。我不是很确定,但我认为该查询必须锁定所有内容并将所有其他查询放入队列中。

我没有在慢查询日志中注意到它,因为它被隐藏在由这个愚蠢查询导致的所有其他慢查询之下。

我希望这可以帮助其他遇到类似问题的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    相关资源
    最近更新 更多