2017-07-13 1 views
0

J'ai une requête qui tourne depuis environ 2 heures ces derniers jours. Mais auparavant cela ne prenait que 2 à 3 minutes de temps. Je ne pouvais pas trouver la raison de sa lenteur soudaine. Quelqu'un peut-il m'aider à ce sujet? S'il vous plaît trouver la requête ci-dessous explique le plan [! [Entrer image description ici] [1]] [1] ...mysql Les performances de la requête sont faibles

select 
IFNULL(EMAIL,'') as EMAIL, 
IFNULL(SITE_CD,'') as SITE_CD, 
IFNULL(OPT_TYPE_CD,'') as OPT_TYPE_CD, 
IFNULL(OPT_IN_IND,'') as OPT_IN_IND, 
IFNULL(EVENT_TSP,'') as EVENT_TSP, 
IFNULL(APPLICATION,'') as APPLICATION 
from (
SELECT newsletter_entry.email email, 
     newsletter.site_cd site_cd, 
     REPLACE (newsletter.TYPE, 'OPTIN_','') opt_type_cd, 
     CASE 
     WHEN newsletter_event_temp.post_status = 'SUBSCRIBED' THEN 'Y' 
       WHEN newsletter_event_temp.post_status = 'UNSUBSCRIBED' THEN 
'N' 
      ELSE '' 
     END 
     opt_in_ind, 
     newsletter_event_temp.event_date event_tsp, 
     entry_context.application application 
FROM amg_toolkit.newsletter_entry, 
     amg_toolkit.newsletter, 
    (select NEWSLETTER_EVENT.* from amg_toolkit.NEWSLETTER_EVENT, 
amg_toolkit.entry_context where newsletter_event.EVENT_DATE >= '2017-07-11 
00:01:23' AND newsletter_event.EVENT_DATE < '2017-07-11 01:01:23' and 
newsletter_event.ENTRY_CONTEXT_ID = entry_context.ENTRY_CONTEXT_ID and 
entry_context.APPLICATION != 'feedbackloop') newsletter_event_temp, 
     amg_toolkit.entry_context 
WHERE newsletter_entry.newsletter_id = newsletter.newsletter_id 
     AND newsletter_entry.newsletter_entry_id = 
      newsletter_event_temp.newsletter_entry_id 
     AND newsletter.TYPE IN ('OPTIN_PRIM', 'OPTIN_THRD', 'OPTIN_WRLS') 
     AND newsletter_event_temp.entry_context_id NOT IN 
      (select d.ENTRY_CONTEXT_ID from amg_toolkit.sweepstake a, 
amg_toolkit.sweepstake_entry b, amg_toolkit.user_entry c, 
amg_toolkit.entry_context d where a.exclude_data = 'Y' and 
a.sweepstake_id=b.sweepstake_id and b.USER_ENTRY_ID=c.USER_ENTRY_ID and 
c.ENTRY_CONTEXT_ID = d.ENTRY_CONTEXT_ID) 
     AND newsletter_event_temp.entry_context_id = 
      entry_context.entry_context_id 
     AND newsletter_event_temp.event_date >= '2017-07-11 00:01:23' 
     AND newsletter_event_temp.event_date < '2017-07-11 01:01:23') a;` 




    [1]: https://i.stack.imgur.com/cgsS1.png 
+0

Si vous ne connaissez pas un DBA, il est peut-être temps d'en trouver un. Soit cela ou couper cette requête à la taille. – tadman

+0

Je suis ce DBA et je ne connais pas la cause première de ce problème. Pouvez-vous m'expliquer la solution? – saravana

+0

Commencez à supprimer des éléments de votre requête jusqu'à ce qu'ils ne soient plus lents, puis ajoutez des éléments jusqu'à ce que vous puissiez identifier la cause du problème. Comme toujours. Vous voudrez également vérifier attentivement votre couverture d'index. Chaque fois que je vois une requête aussi importante, je sais que les performances vont être mauvaises. C'est très difficile d'avoir ce genre de monstre performant. – tadman

Répondre

0

ne l'utilise. * sélectionnez uniquement les colonnes de données que vous utilisez dans votre question.

Évitez les sous-sélections imbriquées si vous n'en avez pas besoin.

Je ne vois pas un besoin pour eux dans cette requête. Vous interrogez les données 3 fois de cette façon au lieu d'une seule fois.

La lenteur peut s'expliquer par une requête inefficace ayant à traiter des tables qui ont un nombre croissant d'enregistrements.

"Not in" requiert beaucoup de ressources. Pouvez-vous faire cela d'une meilleure manière en évitant de "pas dans" la logique?

0

JOINs sont généralement plus rapides que les sous-requêtes. NOT IN (SELECT ...) peut généralement être transformé en LEFT JOIN ... WHERE id IS NULL.

Qu'est-ce que le a dans a.exclude_data? On dirait une erreur de syntaxe.

Ces indices sont susceptibles d'aider:

newsletter_event: INDEX(ENTRY_CONTEXT_ID, EVENT_DATE) -- in this order 

Vous devez également pour newsetter_event_temp, mais puisque ce n'est pas possible, quelque chose doit donner. Quelle version de MySQL utilisez-vous? Peut-être que vous pourriez réellement CREATE TEMPORARY TABLE et ADD INDEX.