it-swarm.com.de

Wie funktioniert ORDER BY FIELD () in MySQL intern?

Ich verstehe, wie die Klausel ORDER BY Funktioniert und wie die Funktion FIELD() funktioniert. Was ich verstehen möchte, ist, wie die beiden zusammenarbeiten, um zu sortieren. Wie werden die Zeilen abgerufen und wie wird die Sortierreihenfolge abgeleitet?

+----+---------+
| id |  name   |
+----+---------+
|  1 | stan    |
|  2 | kyle    |
|  3 | kenny   |
|  4 | cartman |
+----+---------+ 

SELECT * FROM mytable WHERE id IN (3,2,1,4) ORDER BY FIELD(id,3,2,1,4)

Die obige Abfrage führt zu

+----+---------+
| id |  name   |
+----+---------+
|  3 | kenny   |
|  2 | kyle    |
|  1 | stan    |
|  4 | cartman |
+----+---------+ 

etwas ähnliches wie ORDER BY 3, 2, 1, 4 zu sagen

FRAGEN

  • Wie funktioniert das intern?
  • Wie erhält MySQL die Zeilen und berechnet die Sortierreihenfolge?
  • Woher weiß MySQL, dass es nach der ID-Spalte sortieren muss?
41
itz_nsn

Für die Aufzeichnung

SELECT * FROM mytable WHERE id IN (1,2,3,4) ORDER BY FIELD(id,3,2,1,4);

sollte auch funktionieren, da Sie die Liste nicht in der WHERE -Klausel bestellen müssen

Wie es funktioniert,

  • FIELD () ist eine Funktion, die die Indexposition einer durch Kommas getrennten Liste zurückgibt, wenn der gesuchte Wert vorhanden ist .

  • Die ORDER BY - Werte werden danach ausgewertet, was FIELD () zurückgibt

Sie können alle Arten von ausgefallenen Bestellungen erstellen

Verwenden Sie beispielsweise die Funktion IF ()

SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0),FIELD(id,3,2,1,4);

Dadurch werden die ersten 4 IDs oben in der Liste angezeigt. Andernfalls werden sie unten angezeigt. Warum?

Im ORDER BY Erhalten Sie entweder 0 oder 1.

  • Wenn die erste Spalte 0 ist, lassen Sie eine der ersten 4 IDs erscheinen
  • Wenn die erste Spalte 1 ist, lassen Sie sie anschließend erscheinen

Lassen Sie es uns mit DESC in der ersten Spalte umdrehen

SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0) DESC,FIELD(id,3,2,1,4);

Im ORDER BY Erhalten Sie immer noch entweder 0 oder 1.

  • Wenn die erste Spalte 1 ist, lassen Sie alles andere als die ersten 4 IDs erscheinen.
  • Wenn die erste Spalte 0 ist, lassen Sie die ersten 4 IDs in der ursprünglichen Reihenfolge erscheinen

IHRE TATSÄCHLICHE FRAGE

Wenn Sie ernsthaft Interna dazu wollen, gehen Sie zu Seiten 189 und 192 des Buches

(MySQL Internals

für einen wirklich tiefen Tauchgang.

Im Wesentlichen gibt es eine C++ - Klasse namens ORDER *order (Der Ausdrucksbaum ORDER BY). In JOIN::prepare Wird *order In einer Funktion namens setup_order() verwendet. Warum in der Mitte der JOIN Klasse? Jede Abfrage, auch a Die Abfrage für eine einzelne Tabelle wird immer als JOIN verarbeitet (siehe meinen Beitrag Gibt es einen Ausführungsunterschied zwischen einer JOIN-Bedingung und einer WHERE-Bedingung? )

Der Quellcode für all dies ist sql/sql_select.cc

Offensichtlich wird der Baum ORDER BY Die Auswertung von FIELD(id,3,2,1,4) enthalten. Somit sind die Zahlen 0,1,2,3,4 die Werte, die sortiert werden, während ein Verweis auf die betreffende Zeile enthalten ist.

68
RolandoMySQLDBA

Vielleicht ist dies zu weit vom eigentlichen Code entfernt, also nicht niedrig genug von dem, was Sie wollten:

Wenn MySQL den Index nicht zum Abrufen von Daten in sortierter Reihenfolge verwenden kann, wird eine temporäre Tabelle/Ergebnismenge mit allen ausgewählten Spalten und einigen zusätzlichen Daten erstellt. Eine davon ist eine Art Spalte zum Speichern der Ergebnisse des ORDER BY-Ausdruckswerts für jede Zeile. dann sendet es diese tmp-Tabelle an eine "filesort" -Rutine mit Informationen darüber, nach welcher Spalte sortiert werden soll. Danach sind die Zeilen in sortierter Reihenfolge, sodass sie einzeln ausgewählt und ausgewählte Spalten zurückgegeben werden können.

1
jkavalik