繁体   English   中英

如何避免子查询获得性能

[英]how to avoid sub-query to gain performance

我有一个报告查询,其中有2个长子查询

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

说明显示

| 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'

不太清楚,但我认为这是似乎需要全面扫描的问题

比我将所有子查询更改为视图(创建视图作为选择子查询),结果是相同的

感谢您的任何建议

子查询和视图在大多数情况下都会在速度上为您提供相同的结果。

如果您的子查询不是variabe,请考虑创建与视图具有相同结构的表,并偶尔执行以下操作:

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

...以缓存您的子查询数据。 如果正确地建立索引,它将减少边缘查询在表中存储子查询结果所浪费的时间,如果数据不经常更改,或者至少如果您不需要每秒获取最新信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM