使用MySQL innoDB缓慢更新(无能为力)

时间:2012-01-27 11:16:53

标签: mysql sql innodb

我有一个相当简单的查询,可以超时运行,在其他罕见情况下最多需要30秒。我不清楚导致它的原因。这是我正在谈论的一个例子。

  

的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';
  查询OK,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';
  查询OK,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'SET msm.STATUS ='P'   在哪里msm.memberNo = 7 AND msm.STATUS ='M';
  查询OK,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'SET msm.STATUS ='P'   在哪里msm.memberNo = 7 AND msm.STATUS ='M';
  查询OK,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查询。为什么即使没有任何行实际更新,此查询也需要执行这么长时间?这个“发送数据”瓶颈可能是什么?

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

  

创建表matchSessionMembers
    matchNo int(11)NOT NULL,
    memberNo int(11)NOT NULL,
    status char(1)NOT NULL默认'M'评论'M =匹配,P =待定,Y =表示是,N =表示否,D =删除',

    muted char(1)NOT NULL默认'N',
    deleted char(1)NOT NULL默认'N',
    regDatetime日期时间DEFAULT NULL,
    exitDatetime日期时间DEFAULT NULL,
    PRIMARY KEY(matchNomemberNo),
    KEY statusstatus),
    KEY FK_matchSessionMembers_memberNomemberNo),
    KEY regDatetimeregDatetime),
    KEY FK_matchSessionMembers_matchNomatchNo),
    约束FK_matchSessionMembers_matchNo外键(matchNo)参考matchSessionsmatchNo),
    约束FK_matchSessionMembers_memberNo外键(memberNo)参考membersmemberNo
  )ENGINE = InnoDB DEFAULT CHARSET = utf8

     

创建表matchSessions
    matchNo int(11)NOT NULL AUTO_INCREMENT,
    memberCount int(11)NOT NULL,
    status char(1)NOT NULL默认'P'评论'P =待定,Y =成功,N =不成功,X =已过期',
    isQuickMatch char(1)NOT NULL默认'N',
    open char(1)NOT NULL默认'N',
    regDatetime日期时间DEFAULT NULL,
    activeDate日期DEFAULT NULL,
    expireDate日期DEFAULT NULL,
    PRIMARY KEY(matchNo),
    KEY statusstatus),
    KEY activeDateactiveDate),
    KEY expireDateexpireDate
  )ENGINE = InnoDB AUTO_INCREMENT = 113912 DEFAULT CHARSET = utf8

1 个答案:

答案 0 :(得分:1)

我明白了。

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

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

我希望这有助于其他有类似问题的人。