2011-08-25 17 views
25

Musiałem przejrzeć kod i natknąłem się na coś, co ktoś zrobił, i nie mogę wymyślić przyczyny, dla której moja droga jest lepsza. I prawdopodobnie nie jest, więc, który jest lepszy/bezpieczniejszy/bardziej wydajny?MAX vs Top 1 - co jest lepsze?

SELECT MAX(a_date) FROM a_table WHERE a_primary_key = 5 GROUP BY event_id 

LUB

SELECT TOP 1 a_date FROM a_table WHERE a_primary_key = 5 ORDER BY a_date 

bym poszedł z 2 opcji, ale nie jestem pewien, dlaczego, a jeśli to prawda.

Odpowiedz

13

Wydajność jest zasadniczo podobna, jeśli tabela jest indeksowana.

Warto zastanowić się jednak: Top sprawia zazwyczaj tylko sens, jeśli jesteś zamawiania wyniki (? Inaczej, top z co)

Zamawiającego rezultatu wymaga więcej przetwarzania.

Min. Nie zawsze wymaga zamówienia. (Po prostu zależy, ale często nie trzeba składać zamówienia przez lub w grupach itp.).

W dwóch przykładach spodziewam się, że plan prędkości/x będzie bardzo podobny. Zawsze możesz sprawdzić swoje statystyki, ale wątpię, by różnica była znacząca.

+1

SQL Server TOP 1 zachowuje się inaczej niż Oracle przy użyciu rowNum = 1. Oracle faktycznie pobiera pierwszą, którą znajdzie PRZED zamówieniem, więc ta metoda jest ważna tylko dla SQL Server. Kolejną zaletą tego TOP 1 vs Max() jest to, że możesz pobrać tyle kolumn, ile chcesz, o ile uwzględnisz odpowiednią kolejność. Przetestowałem używając Max() i znalazłem nawet w GROUP BY, że nie wydaje się, aby uzyskać tylko 1 rekord. Być może ktoś jako silniejszy mojo może powiedzieć, jak uzyskać tylko jeden wiersz, jeśli chcesz uzyskać szczyt z wielu kolumn bez kwerendy? – gordon

10

Są to różne zapytania.

Pierwszy zwraca wiele rekordów (największy a_date dla każdego event_id znaleźć w a_primary_key = 5)

Drugi zwraca jeden rekord (najmniejsza a_date znaleźć w a_primary_key = 5).

+2

o.O pierwsze zapytanie nadal zwraca jeden rekord –

+1

@Shredder Pod warunkiem, że 'a_primary_key' jest tak naprawdę kluczem podstawowym, będzie. Ale jeśli jest to klucz podstawowy, masz tylko jedną datę w 'a_date' i nie potrzebujesz ani' max' ani 'top'. – GSerg

+0

Nawet jeśli nie, to nadal zwróci jeden rekord. http://www.w3schools.com/sql/sql_func_max.asp –

0

MAX i TOP działają inaczej. Twoje pierwsze zapytanie zwróci maksymalną wartość znalezioną dla a_date, która ma a_primary_key = 5 dla każdego znalezionego innego event_id. Drugie zapytanie pobierze po raz pierwszy a_date z a_primary_key = 5 znalezionym w zestawie wyników.

+1

Nie pobierze pierwszej wartości. 'Top', w połączeniu z' order by asc', wybierze najmniejszą wartość. – GSerg

+0

w którym jesteś smokin bro, daj mi trochę tego .. It * will * chwyci pierwszą znalezioną wartość, i tak, w tym przypadku będzie najmniejsza, ponieważ zamówienie przez ASC idzie od najmniejszego do największego, czyniąc pierwszą wartość najmniejszą .. –

5

Dla zapytania mają ten sam wynik, co jest potrzebne:

SELECT MAX(a_date) FROM a_table WHERE a_primary_key = 5 

SELECT TOP 1 a_date FROM a_table WHERE a_primary_key = 5 ORDER BY a_date DESC 

Najlepszym sposobem, aby wiedzieć, co jest szybsze jest sprawdzenie planu kwerend i robić swoje standardy. Istnieje wiele czynników, które wpływają na szybkość, takich jak rozmiar tabeli/sterty, itp. I nawet różne wersje tej samej bazy danych mogą być zoptymalizowane, aby faworyzować jedno zapytanie względem drugiego.

+3

Nie ma potrzeby grupowania według pierwszego przykładu (ponieważ masz tylko jedną grupę na klauzulę WHERE). – Chains

+0

@kuru: Nie jestem pewien, czy możesz użyć funkcji agregacji w/oa grupy przez, ale jeśli tak ... masz rację – vol7ron

+3

Tak długo, jak wybierasz tylko aggs (tak jak w twojej odpowiedzi), jesteś w porządku. Jeśli w selekcji podasz wartość inną niż agresywna, potrzebujesz grupy według. – Chains

0

ja wykonać max i top na jednym stole z 20,00,000+ rekordów, i stwierdził, że Top dać szybciej doprowadzić z rzędu przez niż max lub min funkcji.

Najlepszym sposobem jest wykonanie obu zapytań przez pewien czas i sprawdzenie czasu, który upłynął od połączenia.

Powiązane problemy