4

我的 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  
4

1 回答 1

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
于 2013-04-05T21:38:16.523 回答