【发布时间】: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 警告:0mysql> 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 警告:0mysql> 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 警告:0mysql> 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 警告:0mysql> 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 警告:0mysql> 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(matchNoint(11) NOT NULL,memberNoint(11) NOT NULL,statuschar(1) NOT NULL DEFAULT 'M ' COMMENT 'M=匹配,P=待定,Y=saidYes,N=saidNo,D=deleted',mutedchar(1) NOT NULL DEFAULT 'N',deletedchar(1 ) NOT NULL DEFAULT 'N',regDatetimedatetime DEFAULT NULL,exitDatetimedatetime 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(matchNoint(11) NOT NULL AUTO_INCREMENT,memberCountint(11) NOT NULL,statuschar(1) NOT NULL DEFAULT ' P' COMMENT 'P=待处理,Y=成功,N=不成功,X=过期',isQuickMatchchar(1) NOT NULL DEFAULT 'N',openchar(1) NOT NULL默认'N',regDatetimedatetime 默认空,activeDatedate 默认空,expireDatedate 默认空,
主键 (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.我已经想到了,但我不明白为什么查询时间如此明显不一致。