Rolf B: MySQL Abfrage langsam

Beitrag lesen

Hallo mixmastertobsi,

Felix' Ermahnung kannst Du Dir durchaus zu Herzen nehmen, aber ich glaube, ich habe auch so schon einen Tipp für Dich. Ich weiß nur nicht, ob der Tipp wirklich greift; Deine „fachliche Beschreibung“ weicht doch deutlich von deiner Query ab.

Eigentlich wollte ich Dir ja vorschlagen, von einem LEFT JOIN auf eine NOT EXISTS Abfrage zu wechseln, aber der Explain zeigt, dass mysql das ohnehin schon für Dich gemacht hat. Insofern ist das für die Performance nicht hilfreich. Es könnte aber lesbarer sein und die Absicht der Query deutlicher zum Ausdruck bringen.

Verdächtig ist die "USING WHERE" Angabe in der 2. Zeile des Explain. Diese Angabe bedeutet, dass er außer dem Index-Zugriff noch in die Tabelle schauen muss, um zu prüfen, was da steht. D.h. er führt einen Dateizugriff mehr aus. Du könntest einen Vorteil gewinnen, wenn Du die Spalte Status mit in den Index der Info-Tabelle aufnimmst. Dann kann mysql die Exists-Prüfung allein über den Index befriedigen und muss nicht auf die Datentabelle zurückgreifen.

Die Frage ist aber, ob du nicht auch mit dem existierenden Index auskommst. Du hast ja beschrieben, dass Du prüfen möchtest, ob es zu einer Rechnung KEINEN SATZ IN DER INFO-TABELLE gibt. Deine Query prüft aber, ob es keinen Satz zur Rechnung gibt, der Status 1 hat. Wenn die Status Abfrage nicht wichtig ist, dann lass sie weg und du kannst den Index lassen wie er ist. Wenn doch - ok, dann könnte eine Indexerweiterung helfen.

Oder auch nicht. Problem an einer Index-Erweiterung KANN SEIN, dass damit Updates langsamer werden. Ein "Status" Attribut neigt dazu, sich öfter mal zu ändern. Ist es im Index, muss bei jedem Update auch der Index aktualisiert werden. Wenn der Index der clustered index ist, führt das zu größeren Datenschaufeleien weil er dann die Daten umsortiert. Das ist jetzt eine Abwägungssache. Eventuell musst Du neben den Clustered-Index noch einen Secondary Index setzen. Da hilft nur probieren und messen, welche DB-Operationen durch welche Indexe schneller und langsamer werden.

Query mit NOT EXISTS - sollte genau so schnell sein wie der LEFT JOIN.

select Count(*)
from Rechnungen r
WHERE NOT EXISTS (SELECT * FROM auftrag_info ai
                  WHERE ai.auftragnr = r.auftragnr AND ai.status = '1')

plusminus ein paar Anpassungen an deine persönliche Realität.

Rolf

--
sumpsi - posui - clusi