SELECT查询偶尔会执行很长时间

时间:2013-03-19 13:08:59

标签: mysql performance innodb

我的MySQL InnoDB数据库中存在一个非常奇怪的问题。我有以下查询:

SELECT DISTINCT p.idProject AS idProject, p.name AS name, 0 AS isConfirm
FROM Projects p
    JOIN team_project tp ON (p.idProject = tp.idProject) 
    JOIN projtimes pt ON (p.idProject = pt.idProject) 
    JOIN CalledTimesTbl ctt ON (p.idProject = ctt.idProject)
    LEFT JOIN NextCalls nc ON (ctt.idCustomer = nc.idCustomer 
        AND ctt.idProject = nc.idProject) 
WHERE tp.idTeam = 158
    AND p.activated = 1 
    AND current_date >= p.projStart
    AND current_date < p.confirmStart 
    AND pt.invitesCount < pt.maxPerPresentation
    AND (nc.idCustomer IS NULL OR nc.nextCall < now())
ORDER BY p.name

通常,查询运行正常,但有时 - 例如,当我设置tp.idTeam = 147时,它运行速度非常慢(如10或20秒)。当我创建替代团队并调整正确的表值以使具有不同idTeam值的相同结果时 - 查询将在几分之一秒内执行。

我对查询进行了分析,并注意到当查询执行缓慢时 - 大部分时间都会消耗一件事:

Copying to tmp table      | 12.489197

我有点惊讶的是,查询创建了一个tmp表但是确定 - 每次执行查询时都会创建它 - 当它快速执行时也是如此。 我只是补充说db设计得很好,所有都需要外键等等。

如何找到缓慢执行的来源并消除它?

编辑:EXPLAIN结果:

id   select_type   table   type     possible_keys                    key              key_len   ref                                                   rows   Extra                             
1    SIMPLE        tp      ref      unique_row,idTeam                idTeam           4         const                                                 56     Using temporary; Using filesort   
1    SIMPLE        p       eq_ref   PRIMARY,projStart,confirmStart   PRIMARY          4         xxx.tp.idProject                                      1      Using where                       
1    SIMPLE        pt      ref      uniq_projtimes                   uniq_projtimes   4         xxx.tp.idProject                                      1      Using where; Distinct             
1    SIMPLE        ctt     ref      idProject                        idProject        4         xxx.tp.idProject                                      3966   Using index; Distinct             
1    SIMPLE        nc      eq_ref   PRIMARY,idProject                PRIMARY          8         xxx.ctt.idCustomer,xxx.tp.idProject                   1      Using where; Distinct     

EDIT2:EXPLAIN EXTENDED的结果首先是快速查询,第二个是慢速查询。

id   select_type   table   type     possible_keys                    key              key_len   ref                                           rows    filtered   Extra                  1    SIMPLE        tp      ref      unique_row,idTeam                idTeam           4         const                                                 1       100        Using temporary         
1    SIMPLE        p       eq_ref   PRIMARY,projStart,confirmStart   PRIMARY          4         xxx.tp.idProject                              1       100        Using where             
1    SIMPLE        pt      ref      uniq_projtimes                   uniq_projtimes   4         xxx.tp.idProject                              1       100        Using where; Distinct   
1    SIMPLE        ctt     ref      idProject                        idProject        4         xxx.tp.idProject                              46199   100        Using index; Distinct   
1    SIMPLE        nc      eq_ref   PRIMARY,idProject                PRIMARY          8         xxx.ctt.idCustomer,xxx.tp.idProject           1       100        Using index; Distinct  

id   select_type   table   type     possible_keys                    key              key_len   ref                                           rows   filtered   Extra                                
1    SIMPLE        p       eq_ref   PRIMARY,projStart,confirmStart   PRIMARY          4         xxx.ctt.idProject                             1      100        Using where                          
1    SIMPLE        pt      ref      uniq_projtimes                   uniq_projtimes   4         xxx.ctt.idProject                             1      100        Using where; Distinct                
1    SIMPLE        tp      ref      unique_row,idTeam                unique_row       8         xxx.pt.idProject,const                        1      100        Using where; Using index; Distinct   
1    SIMPLE        nc      eq_ref   PRIMARY,idProject                PRIMARY          8         xxx.ctt.idCustomer,xxx.tp.idProject           1      100        Using index; Distinct  

1 个答案:

答案 0 :(得分:0)

尝试此调整后的查询。 (它将加入更少的行)

SELECT DISTINCT p.idProject AS idProject, p.name AS name, 0 AS isConfirm
FROM Projects p
    JOIN projtimes pt ON 
        p.idProject = pt.idProject
        AND p.activated = 1
        AND current_date >= p.projStart
        AND current_date < p.confirmStart
        AND pt.invitesCount < pt.maxPerPresentation
    JOIN team_project tp ON 
        p.idProject = tp.idProject
        AND tp.idTeam = 158
    JOIN CalledTimesTbl ctt ON (p.idProject = ctt.idProject)
    LEFT JOIN NextCalls nc ON (ctt.idCustomer = nc.idCustomer 
        AND ctt.idProject = nc.idProject) 
WHERE (nc.idCustomer IS NULL OR nc.nextCall < now())
ORDER BY p.name