2010-12-03 6 views
0

Ich habe immer noch Probleme folgendeReihenfolge von Ursachen filesort

EXPLAIN EXTENDED SELECT 
    `item`.`id`, 
    `item`.`timestamp`, 
    `item`.`label` 
    FROM 
    item 
WHERE 
    item.dataTypeId=30 
GROUP BY 
    item.id 
ORDER BY 
    item.timestamp DESC 
LIMIT 0,6; 

Id & Zeitstempel ist ein primäres Schlüsselpaar (MEDIUMINT + DATETIME) dataTypeId ist ein Fremdschlüssel (MEDIUMINT) Tabelle als geschaffen InnoDb

Es kann mehr Datensätze mit derselben ID und unterschiedlichen Zeitstempel (Versionen des gleichen Elements) geben. Dies ist der Grund für die Gruppe von.

ich zum Beispiel lesen diese: similar topic on stackoverflow

aber es hat nicht mein Problem zu lösen. Folgendes Indizes

Ich habe versucht, zu erstellen:

  1. Index (dataTypeId, id, Zeitstempel) - in dieser Reihenfolge
  2. Index (dataTypeId, Zeitstempel) - in dieser Reihenfolge
  3. Index auf id
  4. Index auf Zeitstempel

die letzten beiden ein kleines Stück Verzweiflung ist

ich denke, ich muss etwas Grundlegendes vermissen -
aber wirklich nicht wissen, was.
Erwarten Sie nicht die Lösung (es wäre schön :) richtig kicken mich einfach :)

sort_buffer_size ist jetzt 4194288

edit: erklären - keine Indizes

"1" "SIMPLE" "item" "ref" "FK_dataTypeId" "FK_dataTypeId" "4" "const" "5608" "Using where; Using temporary; Using filesort" 

erklären mit Indizes erstellt

"1" "SIMPLE" "item" "ref" "FK_udssDataItem_1,testIndexType,testIndexTypeTimestamp,testIndexTypeIdTime" "FK_udssDataItem_1" "4" "const" "5632" "Using where; Using temporary; Using filesort" 
+1

Datei Sortierung bedeutet nicht langsam, bitte werfen Sie die ** EXPLAIN ** Abfrage Ergebnisse – ajreal

+0

die Abfrage über 5000 Zeile dauert 2 Sekunden, habe ich meine ursprüngliche Abfrage auf Mindestgröße vereinfacht - und versuchen Schritt für Schritt mit Ausnahme von einem möglicher Grund nach dem anderen. Der einzige "heiße Punkt" in EXPLAIN ist der mit "filesort". Weitere Zeilen werden über Indizes mit geringer Anzahl von Zeilen verarbeitet ... – jakub

+0

Zuerst gruppieren Sie nach ID, aber Sie sortieren nach Zeitstempel ... das ergibt keinen logischen Sinn. Sie sollten wahrscheinlich nach einer Aggregatfunktion (AVG/MAX/MIN) auf dem Zeitstempel sortieren. – Riedsio

Antwort

1

Es gibt ein Problem mit Ihrer Abfrage. Wenn Sie die "Gruppe nach ID" machen, haben Sie möglicherweise unterschiedliche Zeitstempel für dieselbe ID und haben nicht angegeben, welche zu verwenden ist (Min(), max() usw.). Ein ähnliches Problem tritt bei dem Feld "Label" auf.

http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html

So müssen Sie Agregate Funktionen auf Zeitstempel und beschriften sonst die zurückgegebenen Werte unvorhersehbar sein kann.

Da Sie nach ID und der Sortierung nach Timestamp gruppieren, extrahiert MySQL einen Timestamp pro Gruppe, so dass ein Index nicht wirklich viel hilft. Sie können den Dateibereich mit dieser Abfrage möglicherweise nicht loswerden.

+0

OMG Ich bin soooo Anfänger, wenn ich sehe, was ich geschrieben habe, dann alle Antworten. Ich wusste auch nicht, dass filesort nicht unbedingt langsam bedeutet. Deshalb habe ich diesen Teil der Abfrage zuerst vermutet. Vielen Dank für Ihren Rat und den verlinkten Artikel. – jakub

1

Also Ihr Frage ist "Wie kann ich Dateisort auf Ihrer Anfrage vermeiden"?
In diesem Fall müssen Sie alle Spalten in Ihrem Index in Ihrer where-Klausel haben, damit MySQL eine Indexsortierung durchführt.

mit der ID, Zeitstempel Primärschlüssel Sie müssen

where id = myid and item.timestamp between (t1,t2) 

Auch passen sie von Bereichen mit offenem Ende (und Zeitstempel < now())

Ich bin nicht sicher, was datatypeID ist, aber Wenn dies Ihre einzige Bedingung ist, sollte das Hinzufügen eines Index nur für diese Spalte auch eine Indexsortierung vorschlagen. aber Sie müssen möglicherweise den Index auf (timestamp, datypID) ... in dieser Reihenfolge ... erstellen.

+0

Wie @ajreal erwähnt, ist ein Filesort nicht immer schlecht. Ich habe in letzter Zeit viel Zeit damit verbracht, einen Filesort loszuwerden, nur damit es am Ende kaum einen Unterschied macht. Wenn Sie die Speicher zur Verfügung haben, ist eine einfache Alternative, Ihr Verzeichnis/tmp einfach auf/dev/shm zu verlinken, so dass eine Dateisortierung im Wesentlichen eine Speichersortierung ist. –

+0

Ja, das sollte meine Frage sein. Aber ich setze immer noch alle Spalten in die Anweisung in den Index - immer noch Dateisortierung. Dann lege ich alle Spalten in where und order statement (filesort). Dann versuchte andere Kombination (wie ich schrieb). – jakub