Ich verstehe, wie ORDER BY
Klausel funktioniert und wie die FIELD()
Funktion funktioniert. Ich möchte verstehen, wie beide 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
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?
SELECT *, FIELD(id,3,2,1,4) AS f FROM mytable WHERE id IN (3,2,1,4);
Fügen Sie dannORDER BY f
oder hinzuORDER BY FIELD(id,3,2,1,4)
und versuchen Sie es erneut.Antworten:
Für die Aufzeichnung
sollte auch funktionieren, da Sie die Liste in der
WHERE
Klausel nicht bestellen müssenWie es funktioniert,
FIELD () ist eine Funktion, die die Indexposition einer durch Kommas getrennten Liste zurückgibt, wenn der gesuchte Wert existiert.
Die
ORDER BY
Werte werden von dem ausgewertet, was FIELD () zurückgibtSie können alle Arten von ausgefallenen Bestellungen erstellen
Zum Beispiel mit der Funktion IF ()
Dadurch werden die ersten 4 IDs oben in der Liste angezeigt. Andernfalls wird sie unten angezeigt. Warum?
In der
ORDER BY
erhält man entweder 0 oder 1.Lassen Sie es uns mit DESC in der ersten Spalte spiegeln
In der
ORDER BY
erhält man entweder noch 0 oder 1.IHRE AKTUELLE FRAGE
Wenn Sie diesbezüglich ernsthafte Interna wünschen, lesen Sie die Seiten 189 und 192 des Buches
für einen tiefen tauchgang.
Im Wesentlichen gibt es eine C ++ - Klasse namens
ORDER *order
(DerORDER BY
Ausdrucksbaum). InJOIN::prepare
,*order
wird in einer aufgerufenen Funktion verwendetsetup_order()
. Warum mitten in derJOIN
Klasse? Jede Abfrage, auch eine 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 das ist
sql/sql_select.cc
Offensichtlich wird der
ORDER BY
Baum die Bewertung von enthaltenFIELD(id,3,2,1,4)
. Somit sind die Zahlen 0, 1, 2, 3, 4 die Werte, die sortiert werden, während ein Verweis auf die betreffende Zeile geführt wird.quelle
N
Werte in beidenIN
undFIELD
. In diesem BeispielN=4
. Verstehe ich richtig, dass diese Abfrage mindestens~N^2
Vorgänge ausführen wird. Weil bei jederFIELD
Berechnung~N
für jede Zeile ein Vergleich durchgeführt wird. Wenn ja, ist das ziemlich langsam für großeN
Vielleicht ist es kein sehr guter Ansatz?FIELD()
Funktion sollte eineO(1)
Operation sein, daFIELD()
sie einen numerischen Index hatid
. Ich sehe also nichts anderes alsO(n)
Zeilen. Ich seheFIELD()
keine iterative Operation, wieGREATEST()
sie nötig wäre.FIELD
hatN
Argumente zu vergleichen , dann wird es ausführenN
Vergleiche. Wie kann es sonst passieren, dass eine Nummer mitN
anderen Nummern verglichen wird, wenn dies nicht der Fall istO(N)
? Die einzige Möglichkeit, die ich mir vorstellen kann, ist eine Art Optimierung durch eine spezielle Datenstruktur wie einen Hash oder einen Baum von Argumenten. Eigentlich weiß ich, dassIN
das eine solche Optimierung hat. Ich weiß es nichtFIELD
. Was meinen Sie mit einem "numerischen Index"?Vielleicht ist dies zu weit vom eigentlichen Code entfernt, so dass es nicht niedrig genug von dem ist, was Sie wollten:
Wenn MySQL den Index nicht zum Abrufen von Daten in sortierter Reihenfolge verwenden kann, erstellt es eine temporäre Tabelle / Ergebnismenge mit allen ausgewählten Spalten und einigen zusätzlichen Daten. Eine davon ist eine Art Spalte zum Speichern der Ergebnisse des ORDER BY-Ausdruckswerts für jede Zeile. dann sendet er diese tmp-Tabelle an einen "filesort" -Rutine mit Informationen, 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.
quelle
FIELD
Funktion berechnet wird. Ich befürchte, dass dies erhebliche Auswirkungen auf die Leistung haben könnte.