MySQL: Gruppiert / Geordnet / Links Verknüpfen Sie die Abfrage sehr langsam

8

Ich habe ein Problem mit einer Abfrage, die viel zu lange dauert (über zwei Sekunden nur für diese einfache Abfrage).

Auf den ersten Blick scheint es sich um ein Indizierungsproblem zu handeln, alle verbundenen Felder sind indiziert, aber ich kann nicht finden, was ich sonst noch indexieren muss, um dies zu beschleunigen. Sobald ich die Felder, die ich brauche, zur Abfrage hinzufüge, wird es noch langsamer.

%Vor%

Anzahl der Tabellenzeilen (~): tabledef_Jobs (108k), tabledef_JobCatLink (109k), tabledef_Companies (100), tabledef_Applications (50k)

Hier können Sie die Beschreibung sehen. Die Verwendung von temporär scheint die Abfrage zu verlangsamen:

Tabellenindex Screenshots:

Jede Hilfe wäre sehr willkommen

BEARBEITEN MIT ANTWORT

Final verbesserte Abfrage mit @Steve (markierte Antwort). Letztendlich wurde die letzte Abfrage von ~ 22s auf ~ 0.3s reduziert:

%Vor%     
Tom Kay 07.03.2013, 13:46
quelle

1 Antwort

6

Richtig, ich werde einen Stich bekommen.

Es scheint, dass das Query Optimizer nicht einen Index verwenden kann, um die Abfrage für die Tabelle Tabledef_Jobs zu erfüllen.

Sie haben ein Offset-Limit und dies mit der Kombination Ihrer ORDER BY kann die Datenmenge vor dem Beitritt nicht begrenzen und muss daher nach job_id gruppieren, was ein PK und schnell ist - aber dann diese Daten bestellen (temporär) Tabelle und ein Filesort), bevor Sie das meiste dieser Daten beschränken und wegwerfen, bevor Sie schließlich alles andere dazu bringen.

Ich würde vorschlagen, den Jobs von "job_id, date_posted"

einen zusammengesetzten Index hinzuzufügen

Optimiere also zuerst die Basisabfrage:

%Vor%

Dann können Sie die Joins und die endgültige Struktur kombinieren, um eine effizientere Abfrage zu erstellen.

Ich kann es nicht vorübergehen lassen, ohne zu empfehlen, dass Sie Ihren Limit-Offset überdenken. Dies ist in Ordnung für kleine initiale Offsets, aber wenn es anfängt, groß zu werden, kann dies ein Hauptgrund für Leistungsprobleme sein. Lassen Sie uns zum Beispiel sagen, dass Sie dies für die Paginierung verwenden, was passiert, wenn sie Seite 3000 wollen - Sie werden

verwenden %Vor%

Das wird dann 3050 Zeilen sammeln / die Daten manipulieren und dann die ersten 3000 wegwerfen.

[ 1 bearbeiten - Als Antwort auf die folgenden Kommentare]

Ich werde mit einigen weiteren Informationen erweitern, die Sie in die richtige Richtung weisen könnten. Leider gibt es keine einfache Lösung, die es beheben kann, Sie müssen verstehen, warum dies geschieht, um es zu beheben. Einfach das LIMIT oder ORDER BY zu entfernen funktioniert möglicherweise nicht und schließlich möchten Sie nicht als Teil Ihrer Abfrage entfernen, was bedeutet, dass es für einen bestimmten Zweck da sein muss.

Optimieren Sie zuerst die einfache Basisabfrage, die normalerweise viel einfacher ist als die Arbeit mit mehrfach verknüpften Datensätzen.

Trotz aller Angriffe, die es erhält gibt es nichts mit filesort . Manchmal ist dies die einzige Möglichkeit, die Abfrage auszuführen. Einverstanden, es kann die Ursache für viele Leistungsprobleme sein (besonders bei größeren Datensätzen), aber das ist normalerweise nicht der Fehler von filesort, sondern die zugrundeliegende Abfrage / Indexierungsstrategie.

Innerhalb von MySQL können Sie keine Indizes mischen oder Reihenfolgen desselben Indexes mischen - die Ausführung einer solchen Aufgabe führt zu einem Dateisort.

Wie gesagt, ich habe vorgeschlagen, einen Index für date_posted zu erstellen und dann:

zu verwenden %Vor%     
Steve 07.03.2013, 14:29
quelle