Rozumiem, jak ORDER BY
działa klauzula i jak FIELD()
działa ta funkcja. Chcę zrozumieć, jak oboje pracują razem przy sortowaniu. W jaki sposób pobierane są wiersze i jak wyliczana jest kolejność sortowania
+----+---------+
| 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)
Powyższe zapytanie spowoduje
+----+---------+
| id | name |
+----+---------+
| 3 | kenny |
| 2 | kyle |
| 1 | stan |
| 4 | cartman |
+----+---------+
coś podobnego do powiedzenia ORDER BY 3, 2, 1, 4
PYTANIA
- Jak to działa wewnętrznie?
- W jaki sposób MySQL pobiera wiersze i oblicza porządek sortowania?
- Skąd MySQL wie, że musi sortować według kolumny id?
SELECT *, FIELD(id,3,2,1,4) AS f FROM mytable WHERE id IN (3,2,1,4);
następnie dodajORDER BY f
lubORDER BY FIELD(id,3,2,1,4)
spróbuj ponownie.Odpowiedzi:
Dla przypomnienia
powinien również działać, ponieważ nie musisz zamawiać listy w
WHERE
klauzuliJeśli chodzi o to, jak to działa,
FIELD () to funkcja, która zwraca pozycję indeksu listy rozdzielanej przecinkami, jeśli szukana wartość istnieje.
Te
ORDER BY
wartości są oceniane przez co polu () powracaMożesz tworzyć różnego rodzaju fantazyjne zamówienia
Na przykład, stosując IF () funkcji
Spowoduje to, że pierwsze 4 identyfikatory pojawią się na górze listy, w przeciwnym razie pojawi się na dole. Czemu?
W
ORDER BY
albo dostajesz 0 albo 1.Odwróćmy to za pomocą DESC w pierwszej kolumnie
W
ORDER BY
dalszym ciągu dostajesz 0 lub 1.TWOJA RZECZYWISTA PYTANIE
Jeśli poważnie chcesz mieć na to elementy wewnętrzne, przejdź do stron 189 i 192 Księgi
na głębokie nurkowanie.
Zasadniczo istnieje klasa C ++ o nazwie
ORDER *order
(ORDER BY
Drzewo wyrażeń). WJOIN::prepare
,*order
jest używana w funkcji o nazwiesetup_order()
. Dlaczego w środkuJOIN
klasy? Każde zapytanie, nawet zapytanie dotyczące pojedynczej tabeli, jest zawsze przetwarzane jako JOIN (Zobacz mój post Czy istnieje różnica w wykonywaniu między warunkiem JOIN a warunkiem WHERE? )Kod źródłowy tego wszystkiego to
sql/sql_select.cc
Najwyraźniej
ORDER BY
drzewo będzie miało ocenęFIELD(id,3,2,1,4)
. Tak więc liczby 0,1,2,3,4 są wartościami sortowanymi z odniesieniem do danego wiersza.źródło
N
wartości zarówno w, jakIN
iFIELD
. W tym przykładzieN=4
. Czy rozumiem poprawnie, że to zapytanie wykona co najmniej~N^2
operacje. Ponieważ każdeFIELD
obliczenie dokonuje~N
porównań raz dla każdego wiersza. Jeśli tak, jest to dość powolne jak na dużeN
Może to nie jest bardzo dobre podejście?FIELD()
Funkcja powinna byćO(1)
operacją, ponieważFIELD()
ma indeks liczbowyid
. Więc nie widzę nic innego, jakO(n)
na podstawie wierszy. Nie widzęFIELD()
wykonywania operacji iteracyjnych, któreGREATEST()
byłyby konieczne.FIELD
maN
argumenty do porównania, wykonaN
porównania. Jak inaczej będzie porównywać jedną liczbę zN
innymi liczbami, jeśli nie robiąc tegoO(N)
? Jedyną możliwością, jaką mogę wymyślić, jest jakaś optymalizacja poprzez specjalną strukturę danych, taką jak skrót lub drzewo argumentów. Właściwie wiem, żeIN
ma taką optymalizację. Nie wiem, oFIELD
. Co rozumiesz przez „indeks liczbowy”?Być może będzie to zbyt daleko od rzeczywistego kodu, więc nie będzie wystarczająco niskiego poziomu od tego, co chciałeś:
Gdy MySQL nie może użyć indeksu do pobierania danych w posortowanej kolejności, tworzy tymczasową tabelę / zestaw wyników ze wszystkimi wybranymi kolumnami i pewnymi dodatkowymi danymi - jedna z nich jest pewnego rodzaju kolumną do przechowywania wyników wartości wyrażenia ORDER BY dla każdego wiersza - następnie wysyła tę tabelę tmp do rutine „fileort” z informacją, według której kolumny posortować. Następnie wiersze są posortowane, dzięki czemu można je wybierać jeden po drugim i zwracać wybrane kolumny.
źródło
FIELD
obliczania funkcji. Obawiam się, że może to mieć znaczący wpływ na wydajność.