2010-06-02 4 views
0

j'ai une requête de rapports qui ont 2 à long sous-requêtecomment éviter la sous-requête pour obtenir des performances

SELECT r1.code_centre, r1.libelle_centre, r1.id_equipe, r1.equipe, r1.id_file_attente, 
r1.libelle_file_attente,r1.id_date, r1.tranche, r1.id_granularite_de_periode,r1.granularite, 
r1.ContactsTraites, r1.ContactsenParcage, r1.ContactsenComm, r1.DureeTraitementContacts, 
r1.DureeComm, r1.DureeParcage, r2.AgentsConnectes, r2.DureeConnexion, r2.DureeTraitementAgents, 
r2.DureePostTraitement 
FROM 
    (SELECT cc.id_centre_contact, cc.code_centre, cc.libelle_centre, a.id_equipe, a.equipe, 
    a.id_file_attente, f.libelle_file_attente, a.id_date, g.tranche, g.id_granularite_de_periode, 
    g.granularite, sum(Nb_Contacts_Traites) as ContactsTraites,  
    sum(Nb_Contacts_en_Parcage) as ContactsenParcage,  
    sum(Nb_Contacts_en_Communication) as ContactsenComm, 
    sum(Duree_Traitement/1000) as DureeTraitementContacts, 
    sum(Duree_Communication/1000 + Duree_Conference/1000 + Duree_Com_Interagent/1000) as DureeComm, 
    sum(Duree_Parcage/1000) as DureeParcage  
    FROM agr_synthese_activite_media_fa_agent a, centre_contact cc, 
    direction_contact dc, granularite_de_periode g, media m, file_attente f     
    WHERE m.id_media = a.id_media     
    AND cc.id_centre_contact = a.id_centre_contact     
    AND a.id_direction_contact = dc.id_direction_contact     
    AND dc.direction_contact ='INCOMING'     
    AND a.id_file_attente = f.id_file_attente     
    AND m.media = 'PHONE'     
    AND ( (g.valeur_min = date_format(a.id_date,'%d/%m') and g.granularite = 'Jour')        
    or (g.granularite = 'Heure' and a.id_th_heure = g.id_granularite_de_periode)  )  
    GROUP by cc.id_centre_contact, a.id_equipe, a.id_file_attente, a.id_date, g.tranche, 
    g.id_granularite_de_periode)  r1,  

    (  
     (SELECT cc.id_centre_contact,cc.code_centre, cc.libelle_centre, a.id_equipe, a.equipe, 
     a.id_date, g.tranche, g.id_granularite_de_periode,g.granularite,  
     count(distinct a.id_agent) as AgentsConnectes,  
     sum(Duree_Connexion/1000) as DureeConnexion,  
     sum(Duree_en_Traitement/1000) as DureeTraitementAgents, 
     sum(Duree_en_PostTraitement/1000) as DureePostTraitement 
     FROM activite_agent a, centre_contact cc, granularite_de_periode g  
     WHERE ( g.valeur_min = date_format(a.id_date,'%d/%m') and g.granularite = 'Jour')      
     AND cc.id_centre_contact = a.id_centre_contact   
     GROUP BY cc.id_centre_contact, a.id_equipe, a.id_date, g.tranche, g.id_granularite_de_periode) 
    UNION  
     (SELECT cc.id_centre_contact,cc.code_centre, cc.libelle_centre, a.id_equipe, a.equipe, 
     a.id_date, g.tranche, g.id_granularite_de_periode,g.granularite,   
     count(distinct a.id_agent) as AgentsConnectes,  
     sum(Duree_Connexion/1000) as DureeConnexion,  
     sum(Duree_en_Traitement/1000) as DureeTraitementAgents, 
     sum(Duree_en_PostTraitement/1000) as DureePostTraitement  
     FROM activite_agent a, centre_contact cc, granularite_de_periode g   
     WHERE ( g.granularite = 'Heure'   
     AND a.id_th_heure = g.id_granularite_de_periode)   
     AND cc.id_centre_contact = a.id_centre_contact   
     GROUP BY cc.id_centre_contact,a.id_equipe, a.id_date, g.tranche, g.id_granularite_de_periode) 
    ) r2  

WHERE r1.id_centre_contact = r2.id_centre_contact 
AND r1.id_equipe = r2.id_equipe AND r1.id_date = r2.id_date 
AND r1.tranche = r2.tranche  AND r1.id_granularite_de_periode = r2.id_granularite_de_periode 
GROUP BY r1.id_centre_contact , r1.id_equipe, r1.id_file_attente, 
r1.id_date, r1.tranche, r1.id_granularite_de_periode  
ORDER BY r1.code_centre, r1.libelle_centre, r1.equipe, 
r1.libelle_file_attente, r1.id_date, r1.id_granularite_de_periode,r1.tranche 

le EXPLAIN

| id | select_type | table | type| possible_keys | key | key_len | ref| rows | Extra          | 
'1', 'PRIMARY', '<derived3>', 'ALL', NULL, NULL, NULL, NULL, '2520', 'Using temporary; Using filesort' 
'1', 'PRIMARY', '<derived2>', 'ALL', NULL, NULL, NULL, NULL, '4378', 'Using where; Using join buffer' 
'3', 'DERIVED', 'a', 'ALL', 'fk_Activite_Agent_centre_contact', NULL, NULL, NULL, '83433', 'Using temporary; Using filesort' 
'3', 'DERIVED', 'g', 'ref', 'Index_granularite,Index_Valeur_min', 'Index_Valeur_min', '23', 'func', '1', 'Using where' 
'3', 'DERIVED', 'cc', 'ALL', 'PRIMARY', NULL, NULL, NULL, '6', 'Using where; Using join buffer' 
'4', 'UNION', 'g', 'ref', 'PRIMARY,Index_granularite', 'Index_granularite', '23', '', '24', 'Using where; Using temporary; Using filesort' 
'4', 'UNION', 'a', 'ref', 'fk_Activite_Agent_centre_contact,fk_activite_agent_TH_heure', 'fk_activite_agent_TH_heure', '5', 'reporting_acd.g.Id_Granularite_de_periode', '2979', 'Using where' 
'4', 'UNION', 'cc', 'ALL', 'PRIMARY', NULL, NULL, NULL, '6', 'Using where; Using join buffer' 
NULL, 'UNION RESULT', '<union3,4>', 'ALL', NULL, NULL, NULL, NULL, NULL, '' 
'2', 'DERIVED', 'g', 'range', 'PRIMARY,Index_granularite,Index_Valeur_min', 'Index_granularite', '23', NULL, '389', 'Using where; Using temporary; Using filesort' 
'2', 'DERIVED', 'a', 'ALL', 'fk_agr_synthese_activite_media_fa_agent_centre_contact,fk_agr_synthese_activite_media_fa_agent_direction_contact,fk_agr_synthese_activite_media_fa_agent_file_attente,fk_agr_synthese_activite_media_fa_agent_media,fk_agr_synthese_activite_media_fa_agent_th_heure', NULL, NULL, NULL, '20903', 'Using where; Using join buffer' 
'2', 'DERIVED', 'cc', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'reporting_acd.a.Id_Centre_Contact', '1', '' 
'2', 'DERIVED', 'f', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'reporting_acd.a.Id_File_Attente', '1', '' 
'2', 'DERIVED', 'dc', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'reporting_acd.a.Id_Direction_Contact', '1', 'Using where' 
'2', 'DERIVED', 'm', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'reporting_acd.a.Id_Media', '1', 'Using where' 

ne le savent pas très clair, mais je pense est le problème de semble il faut balayage complet

que je change toute la sous-requête aux vues (créer l'affichage comme sélection de sous-requête), et le résultat est le même

merci pour tout conseil

+1

Maatkit possède un outil d'explication visuelle. Essayez de l'utiliser pour rendre les résultats EXPLAIN plus clairs. Je ferais mieux de me tuer que d'analyser cela;) –

Répondre

1

La sous-requête et la vue vous donneront la plupart du temps le même résultat en termes de vitesse.

Si votre sous-requête ne variabe, pensez à créer table qui a la même structure que votre point de vue, et à l'occasion:

truncate table my_table; 
insert into my_table select * from my_view; 

... à mettre en cache vos données sous-requête. Si elle est correctement indexée, elle va marginaliser le temps perdu sur le stockage des résultats de la sous-requête dans la table, si les données ne sont pas fréquemment modifiées, ou du moins si vous n'avez pas besoin d'informations actualisées de seconde en seconde.

Questions connexes