2012-04-03 2 views
5

Ich benutze eine einfache MySQL-Abfrage, aber die Leistung ist wirklich schlecht wegen der Verwendung von ORDER BY. Ich kann nicht herausfinden, warum MySQL filesort und temporary verwendet.MySQL-Abfrage mit filesort und temporär

Meine Frage ist:

EXPLAIN 
SELECT * FROM Events 
INNER JOIN EventLogFiles ON ServerID = 42 
AND Events.LogFileID = EventLogFiles.LogFileID 
ORDER BY ReportID DESC , TimeWritten DESC 
LIMIT 100 

Dies ist die Ausgabe von EXPLAIN:

Mysql EXPLAIN output

Tabelle Events Struktur

Table Events structure

Tabelle Events Indizes

Table Events indexes

Tabelle EventLogFiles Struktur

Table EventLogFiles structure

Tabelle EventLogFiles Indizes

Table EventLogFiles indexes

UPDATE:

Ich habe versucht, zwei neue zu schaffen Indizes, aber beide zwingen immer noch MySQL, filesort und temporary zu verwenden.

ALTER TABLE Events ADD INDEX `ReportID_TimeWritten_ServerID_LogFileID` (ReportID DESC, TimeWritten DESC, ServerID, LogFileID) 

ALTER TABLE Events ADD INDEX `ServerID_LogFileID_ReportID_TimeWritten` (ServerID, LogFileID, ReportID DESC, TimeWritten DESC) 
+1

Können Sie die ersten 100 Datensätze ohne Bestellung in eine temporäre Tabelle ausgeben und dann nur diese 100 Datensätze mit einer anderen Abfrage bestellen? –

+1

Fügen Sie dem mehrspaltigen Index Events.LogFileID hinzu. –

+0

Könnten Sie versuchen, Indexe 'ServerID_ReportID_TimeWritten_LogFileID',' ReportID_TimeWritten_ServerID_LogFileID' zu erstellen? Ich denke, einer von ihnen wird helfen. –

Antwort

4

Um den Index sowohl für die Auswahl zu verwenden und das Sortieren, müssen Sie alle folgenden Spalten in einer mehrspaltigen Index auf Ereignisse haben: (ServerID, LogFileID, ReportID, TimeWritten).

Derzeit kann MySQL den vorhandenen mehrspaltigen Index nicht verwenden, da er LogFileID nicht enthält, was in Ihrer -Klausel steht.

Wenn Sie jemals Probleme haben, wo MySQL zuerst von EventLogFiles auswählt, können Sie die INNER JOIN in eine STRAIGHT JOIN ändern, um sicherzustellen, dass MySQL immer zuerst aus Events mit Ihrem Index auswählt.

+0

Marcus, ich folgte Ihrem Rat, aber immer noch das gleiche Problem, haben Sie irgendwelche Ideen? Schlüssel: ServerID_LogFileID_ReportID_TimeWritten | key_len: 4 | Extra: Verwenden von temporär; Verwenden von filesort – koen

+0

Key_len kann nicht 4 für den mehrspaltigen Index sein. Es sollte 16 sein. Ich würde Ihre Abfrage und Index doppelt überprüfen. –

0

Damit ohne temporäre Tabelle und Datei Art arbeiten zu erhalten, müssen Sie einen Index (ServerID, LogFileID, ReportID) und TimeWritten muss seine sequenziellen wie die auto_increment, die Sie in ReportID verwendet haben zu schaffen, so dass die Herstellung ORDER BY ReportID(PK - Order Physical) Sie den filesort entfernen müssen .