2016-07-12 1 views
1

entraîne une surcharge j'ai une requête SQL assez complexe et je ne sais pas comment le faire moins complexe. Si j'essaie de l'exécuter, cela surchargera le db. Si je simplifie un peu, je peux l'exécuter mais cela prend beaucoup de temps. Je suis sûr qu'il existe des moyens beaucoup plus efficaces pour écrire cette requête, mais je n'ai aucune idée de comment. Serait très heureux si quelqu'un pouvait me conduire dans la bonne direction!MySQL Query avec trois tables syndiqués indexé et un-gauche rejoindre DB

SELECT master.C_MASTER_ID, 
     master.C_MASTER_SUMMARY, 
     master.C_MASTER_START, 
     master.C_MASTER_END, 
     master.C_MASTER_LEVEL, 
     master.C_MASTER_SOURCE, 
     NULL AS EVT_HAS_Z, 
     master.C_MASTER_NOTES, 
     master.C_MASTER_SERVICE, 
     c2c.CER_CUSTOMER 
FROM `C_MASTER` master 
LEFT JOIN `c2customer` c2c ON c2c.CER_ID = master.C_MASTER_ID 
WHERE 
    master.C_MASTER_END >= NOW() 
    AND master.C_MASTER_START >= DATE_SUB(NOW(), INTERVAL 21 DAY) 

UNION ALL 

SELECT EVT_ID AS C_MASTER_ID, 
     EVT_SUMMARY, 
     EVT_START_DATE, 
     EVT_END_DATE, 
     NULL AS C_MASTER_LEVEL, 
     NULL AS C_MASTER_SOURCE, 
     EVT_HAS_Z, 
     NULL AS C_MASTER_NOTES, 
     NULL AS C_MASTER_SERVICE, 
     NULL AS CER_CUSTOMER 
FROM C_event 
WHERE EVT_end_date >= NOW() 

UNION ALL 

SELECT 'WHISPER' AS C_MASTER_CHANGE_ID, 
     WISP_SUMMARY, 
     WISP_START_DATE, 
     WISP_END_DATE, 
     NULL AS C_MASTER_LEVEL, 
     NULL AS C_MASTER_SOURCE, 
     NULL AS EVT_HAS_Z, 
     NULL AS C_MASTER_NOTES, 
     NULL AS C_MASTER_SERVICE, 
     NULL AS CER_CUSTOMER 
FROM C_wispering 
WHERE WISP_END_DATE >= NOW() 

Ceci est une petite version simplifiée de ma requête, car otherwhise il aurait été à peine pour managable demander après d'aide.

+1

Quels sont votre nombre de lignes en provenance de la db environ? À quoi ressemblent vos index? sur quels champs et ainsi de suite? – Tikkes

+0

@Tikkes environ 6000 lignes environ. Je n'ai que C_MASTER_ID et CER_ID indexés. J'ai été réticent avec les index parce que je ne sais tout simplement pas beaucoup à ce sujet. Y a-t-il des inconvénients à indexer plus de champs? – sardine

+0

Vous devriez vraiment envisager de lire sur les index dans ce cas. La documentation SQL est exhaustive à ce sujet et peut s'avérer extrêmement utile pour traiter des bases de données plus complexes. Les index peuvent être extrêmement bons lorsqu'ils sont utilisés correctement et améliorer les performances d'une tonne. Bien sûr, mettre des index sur tout ou n'importe quoi a des inconvénients, c'est pourquoi vous devriez mettre des index sur les champs souvent nécessaires ou souvent utilisés dans les requêtes de recherche, aussi les index combinés peuvent être utilisés à votre avantage la plupart du temps. [Documentation sur les index] (https://msdn.microsoft.com/en-us/library/ms175049.aspx) – Tikkes

Répondre

2

Vous devez exécuter chaque requête séparément, afin de déterminer qui est à l'origine des problèmes de performance. Vous pouvez également regarder "expliquer" pour voir les plans.

En main, je peux dire que la première requête bénéficierait d'index sur c_master(C_MASTER_START, C_MASTER_ID) et c2customer(CER_ID, CER_CUSTOMER).

Le second bénéficierait d'un index sur C_event(EVT_end_date). Et le troisième: C_wispering(WISP_END_DATE).

+0

Sidenote à cela cependant, lors de la mise d'un index sur datetimes, il pourrait être sage de ne pas inclure miliseconds/secondes/minutes et viser des heures au lieu de réduire la charge. Plus d'informations sur les performances peuvent également être trouvés sur [cette question stackoverflow] (http://stackoverflow.com/questions/17381875/how-to-improve-performance-for-datetime-filtering-in-sql-server) – Tikkes

+0

Merci beaucoup beaucoup pour la réponse !! Jusqu'à présent, j'ai seulement CER_ID et C_MASTER_ID indexés. J'ai été réticent avec les index simplement parce que je n'en sais pas beaucoup:/- y aurait-il des inconvénients à indexer plus de champs, des risques lors de l'indexation des champs que vous avez suggérés ou puis-je indexer?(J'ai un write-process quotidien sur la DB qui n'a pas été touché jusqu'à présent quand j'ai indexé C_MASTER_ID et CER_ID mais j'ai peur que ça ralentisse beaucoup si je indexe plus) – sardine

+1

@tikkes Avec respect, un DATETIME index est certainement le meilleur moyen de gérer ce genre de chose. La réponse acceptée sur le lien que vous avez fourni contient des informations erronées sur la complexité de l'indexation datetime. –