2016-05-30 11 views
0

Ich brauche eine Verbesserung dieser SQL UPDATE-Abfrage. Die Abfrage muss nur die erste Zeile aktualisieren, aber ich nehme an, dass sie beim Durchlaufen aller Zeilen und beim Ausführen der Unterabfrage für alle Zeilen sehr viel Energie verbraucht, da sie bei großen Datenbanken sehr langsam ist. Irgendwelche Vorschläge?Verbesserung von SQL UPDATE

UPDATE leads l 
    SET status='processing', processor='$processor' 
    WHERE pool IN ($pools) AND status='active' 
    ORDER BY (SELECT count(*) FROM calls c WHERE c.lead = l.id), id ASC 
    LIMIT 1 

UPDATE

Die Langsamkeit in der Tat durch die subselect verursacht wird. Typisch sind 2000-3000 Treffer in der Lead-Tabelle. Der einfachste Weg wäre, eine Spalte in der Leads-Tabelle einzubauen, die Aufrufe manuell zählt, so dass ich den Subselect nicht benötige, aber es ist eine laufende Site, an der diese Änderungen vorgenommen werden müssen, so dass es die Reihenfolge durcheinander bringen würde Ich habe die Spalte jetzt hinzugefügt.

Aber ich denke, es ist der einzige Weg, um den großen Subselect zu vermeiden.

+0

Es klingt wie Sie eine sind vermisst Index? Setzen Sie 'EXPLAIN' vor Ihre Abfrage, um zu sehen, was es tut ... –

+0

probiert' EXPLAIN EXTENDED UPDATE ... '? EXPLAIN EXTENDED gibt weitere Informationen darüber, was genau beim Ausführen der UPDATE-Abfrage passiert. –

Antwort

0

Für mich - Langsamkeit kommt von Subselect. Für jede pool Sie alle calls abfragen, um ihre Anzahl zu berechnen. Stellen Sie zuerst sicher, dass calls.lead indiziert ist. Sie können diesen Zähler in pool behalten und Trigger haben, um das zu wahren. Andere Option ist, diese Informationen innerhalb des Indexes zu behalten, aber ich kann nicht sagen, wie man das auf MySQL verwendet, ein besonders auf unbekannter Version

+0

In der Tat. Ich bin mir nicht ganz sicher, ob ich deine Vorschläge verstehe - kannst du etwas mehr erklären? –

+0

'pool IN ($ pools) AND status = 'active'' - für jeden von ihnen rufen Sie' SELECT count (*) FROM Aufrufe c WHERE c.lead = l.id' - um sie zu sortieren. Stellen Sie zuerst sicher, dass 'c.lead = l.id' index verwendet. Wenn das immer noch zu langsam ist - füge 'count (*) FROM Aufrufe c WHERE c.lead = l.id' als separate Spalte in' pool' hinzu und aktualisiere sie über Trigger –

0

Erstellen eines mehrspaltigen Index auf Lead-Tabelle für die Spalten pool und status wäre die einfachste Weg, um Ihr Update zu beschleunigen. Aber wie viele Zeilen befinden sich wirklich in Ihrer Lead-Tabelle? Und wie viele Zeilen passen zu Ihrer WHERE-Klausel?

mehrspaltigen Index

ALTER TABLE your_schema.leads 
    ADD INDEX faster_update(pool,status) ; 

Auch warum würden Sie nur eine begrenzte Anzahl von Zeilen aktualisieren, die Ihren Kriterien entsprechen? Vielleicht möchten Sie mehr Informationen zu Ihrem Fall geben, um die beste Antwort zu erhalten. Und ein Subselect auf einer 'großen' Tabelle zu verwenden, um es vor der Aktualisierung zu bestellen, klingt nach einer schlechten Idee bezüglich der Ausführungszeit, da die Bestellung leicht länger dauern kann als das Update selbst.

Wenn Ihr nicht wissen, ob ein Index verwendet wird, verwenden Sie den folgenden Code, um Ihre Abfrage zu analysieren:

EXPLAIN EXTENDED SELECT * FROM your_schema.leads 
    WHERE pool IN ($pools) AND status='active' 
    ORDER BY (SELECT count(*) FROM calls c WHERE c.lead = l.id), id ASC 

oder senden Sie einfach das Ergebnis hier