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値で同じ結果を得ると、クエリは数秒で実行されます。

クエリのプロファイリングを行ったところ、クエリの実行が遅い場合、ほとんどの時間を消費するものが 1 つあります。

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高速クエリの最初の結果、低速クエリの 2 番目の結果。

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 に答える