MIN / MAX vs ORDER BY i LIMIT

101

Którą metodę spośród poniższych zapytań uważasz za lepszą? Jakie są twoje powody (wydajność kodu, lepsza konserwacja, mniej WTFery) ...

SELECT MIN(`field`)
FROM `tbl`;

SELECT `field`
FROM `tbl`
ORDER BY `field`
LIMIT 1;
nickf
źródło

Odpowiedzi:

129

W najgorszym przypadku, gdy patrzysz na niezindeksowane pole, użycie MIN()wymaga jednego pełnego przejścia tabeli. Używanie SORTi LIMITwymaga sortowania plików. W przypadku porównania z dużym stołem prawdopodobnie wystąpi znacząca różnica w postrzeganej wydajności. Jako bezsensowny punkt danych, MIN()zajęło to 0,36 sekundy SORTi LIMIT0,84 przeciwko tabeli wierszy 106 000 na moim serwerze deweloperskim.

Jeśli jednak patrzysz na indeksowaną kolumnę, różnica jest trudniejsza do zauważenia (bezsensowny punkt danych to 0,00s w obu przypadkach). Patrząc na wynik wyjaśnienia, wygląda jednak na to, że MIN()jest w stanie po prostu pobrać najmniejszą wartość z indeksu (wiersze „Wybierz tabele zoptymalizowane” i „NULL”), podczas gdy SORTi LIMITnadal musi wykonać uporządkowane przejście indeksu (106 000 wierszy). Rzeczywisty wpływ na wydajność jest prawdopodobnie nieistotny.

Wygląda na MIN()to, że jest do zrobienia - w najgorszym przypadku jest szybszy, w najlepszym nierozróżnialny, to standardowy SQL i najwyraźniej wyraża wartość, którą próbujesz uzyskać. Jedynym przypadkiem, w którym wydaje się, że użycie SORTi LIMITbyłoby pożądane, byłoby, jak wspomniał mson , kiedy piszesz ogólną operację, która znajduje górne lub dolne wartości N z dowolnych kolumn i nie warto pisać operacji specjalnej.

Sean McSomething
źródło
7
o (n) za jedno przejście vs 0 (nlogn) do sortowania
Abhishek Iyer
1
@AbhishekIyer masz całkowitą rację, ale dodałbym „w najgorszym przypadku dla pola nieindeksowanego”.
dmikam
Ta część dotycząca najgorszego niezindeksowanego przypadku jest błędna. Zawsze potrzebujesz pełnego skanowania, skąd jeszcze wiesz, że to minimum lub maksimum? To nie tak, że skanujesz, a wartość krzyczy: „Hej, w końcu mnie znalazłeś! Jestem Jack, max!”.
Robo Robok
W teście z indeksowaną tabelą z 470 milionami wierszy oba zapytania trwają 0,00 s. Jeśli jednak dodamy do zapytań filtr „WHERE pole2 = x”, zapytanie z LIMITem nadal zajmuje 0,00 s, a zapytanie z MIN 0,21 s.
Antonio Cañas Vargas
13
SELECT MIN(`field`)
FROM `tbl`;

Po prostu dlatego, że jest zgodny z ANSI. Limit 1 dotyczy MySql, a TOP dotyczy SQL Server.

Otávio Décio
źródło
Większość DBMS ma limit / offset lub odpowiednik i jest używany w większości aplikacji, nad którymi pracowałem (nie jako alternatywa dla MIN, ale do innych celów, takich jak paginacja).
finnw
@finnw - Zgadzam się, ale przykład pytającego wyraźnie porównywał limit z min.
Otávio Décio
9

Jak zauważyli mson i Sean McSomething , MIN jest preferowane.

Innym powodem, dla którego ORDER BY + LIMIT jest przydatny, jest to, że chcesz uzyskać wartość z innej kolumny niż kolumna MIN.

Przykład:

SELECT some_other_field, field
FROM tbl
ORDER BY field
LIMIT 1
user650654
źródło
4

Myślę, że odpowiedzi zależą od tego, co robisz.

Jeśli masz 1 wyłączone zapytanie, a intencja jest tak prosta, jak określono, wybierz min (pole).

Często jednak tego typu wymagania zmieniają się na - pobierz n najlepszych wyników, pobierz n-ty - m-ty wyniki itp.

Nie sądzę, żeby to był zbyt straszny pomysł, aby zaangażować się w wybraną bazę danych. Zmiana dbs nie powinna być lekka i trzeba zmienić cenę, którą płacisz, wykonując ten ruch.

Po co ograniczać się teraz, z powodu bólu, który możesz odczuwać później lub nie?

Myślę, że dobrze jest pozostać ANSI tak bardzo, jak to możliwe, ale to tylko wskazówka ...

mson
źródło
3

Biorąc pod uwagę akceptowalną wydajność, użyłbym pierwszego, ponieważ jest semantycznie bliższy intencji.
Jeśli wydajność była problemem (większość nowoczesnych optymalizatorów prawdopodobnie zoptymalizuje oba do tego samego planu zapytań, chociaż musisz to przetestować, aby to sprawdzić), to oczywiście użyłbym szybszego.

Charles Bretana
źródło