Jeśli mam stolik
CREATE TABLE users (
id int(10) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
profession varchar(255) NOT NULL,
employer varchar(255) NOT NULL,
PRIMARY KEY (id)
)
i chcę uzyskać wszystkie unikalne wartości profession
pola, co byłoby szybsze (lub zalecane):
SELECT DISTINCT u.profession FROM users u
lub
SELECT u.profession FROM users u GROUP BY u.profession
?
Odpowiedzi:
Są one zasadniczo sobie równe (w rzeczywistości tak właśnie niektóre bazy danych implementują
DISTINCT
pod maską).Jeśli jeden z nich jest szybszy, tak będzie
DISTINCT
. Jest tak, ponieważ chociaż oba są takie same, optymalizator zapytań musiałby wychwycić fakt, żeGROUP BY
nie korzysta się z żadnych członków grupy, tylko ich klucze.DISTINCT
wyjaśnia to wyraźnie, abyś mógł uciec z nieco głupszym optymalizatorem.W razie wątpliwości przetestuj!
źródło
DISTINCT
iGROUP BY
różni się tym,DISTINCT
że nie musi sortować danych wyjściowych, aGROUP BY
domyślnie tak. Jednak w MySQL nawetDISTINCT
+ORDER BY
może być jeszcze szybszy niżGROUP BY
ze względu na dodatkowe wskazówki dla optymalizatora wyjaśnione przez SquareCog.Jeśli masz indeks
profession
, te dwa są synonimami.Jeśli nie, użyj
DISTINCT
.GROUP BY
wMySQL
sortowaniu wyników. Możesz nawet zrobić:i uporządkuj swoje zawody
DESC
.DISTINCT
tworzy tabelę tymczasową i używa jej do przechowywania duplikatów.GROUP BY
robi to samo, ale później sortuje wyraźne wyniki.Więc
jest szybszy, jeśli nie masz indeksu
profession
.źródło
ORDER BY NULL
do,GROUP BY
aby uniknąć sortowania.Wszystkie powyższe odpowiedzi są poprawne, w przypadku DISTINCT w jednej kolumnie vs GROUP BY w jednej kolumnie. Każdy silnik db ma własną implementację i optymalizacje, a jeśli zależy ci na bardzo niewielkiej różnicy (w większości przypadków), musisz przetestować konkretny serwer ORAZ określoną wersję! Ponieważ implementacje mogą ulec zmianie ...
ALE, jeśli wybierzesz więcej niż jedną kolumnę w zapytaniu, DISTINCT będzie zasadniczo inny! Ponieważ w tym przypadku porówna WSZYSTKIE kolumny wszystkich wierszy, zamiast tylko jednej kolumny.
Więc jeśli masz coś takiego:
Powszechnym błędem jest myślenie, że słowo kluczowe DISTINCT rozróżnia wiersze według pierwszej określonej kolumny, ale słowo kluczowe DISTINCT jest w ten sposób ogólnym słowem kluczowym.
Dlatego ludzie muszą uważać, aby nie traktować powyższych odpowiedzi jako poprawnych we wszystkich przypadkach ... Możesz się zdezorientować i uzyskać błędne wyniki, podczas gdy wszystko, czego chciałeś, to optymalizacja!
źródło
Wybierz najprostsze i najkrótsze, jeśli możesz - DISTINCT wydaje się być tym, czego szukasz tylko dlatego, że da Ci DOKŁADNIE odpowiedź, której potrzebujesz i tylko to!
źródło
Grupowanie według jest droższe niż Wyraźny, ponieważ Grupowanie według sortuje wynik, podczas gdy odrębny go unika. Ale jeśli chcesz utworzyć grupę według wydajności, uzyskuj ten sam wynik, co odrębny, podaj porządek przez zero .
jest równe
źródło
SELECT profession FROM users GROUP BY profession
wyraźne mogą być wolniejsze niż grupowanie w niektórych przypadkach w postgresie (nie wiem o innych dbs).
testowany przykład:
http://www.pgsql.cz/index.php/PostgreSQL_SQL_Tricks_I
więc uważaj ... :)
źródło
Wygląda na to, że zapytania nie są dokładnie takie same. Przynajmniej dla MySQL.
Porównać:
Drugie zapytanie zawiera dodatkowo „Korzystanie z sortowania plików” w Extra.
źródło
ORDER BY NULL
doGROUP BY
wersji i będą takie same.W MySQL „
Group By
” wykorzystuje dodatkowy krok:filesort
. Zdaję sobie sprawę, żeDISTINCT
jest szybszyGROUP BY
i to była niespodzianka.źródło
Po ciężkich testach doszliśmy do wniosku, że GROUP BY jest szybszy
WYBIERZ sql_no_cache opnamegroep_intern FROM
telwerken
WHEREopnemergroep
IN (7,8,9,10,11,12,13) grupa według opnamegroep_intern635 suma 0,0944 sekundy Weergave van records 0 - 29 (635 suma, zapytanie duurde 0,0484 s)
WYBIERZ sql_no_cache odrębny (opnamegroep_intern) OD
telwerken
GDZIEopnemergroep
(7,8,9,10,11,12,13)635 suma 0,2117 sekund (prawie 100% wolniej) Weergave van rekordy 0 - 29 (635 suma, zapytanie duurde 0,3468 s)
źródło
(bardziej funkcjonalna nuta)
Są przypadki, w których musisz użyć GROUP BY, na przykład, jeśli chcesz uzyskać liczbę pracowników na pracodawcę:
W takim scenariuszu
DISTINCT u.employer
nie działa dobrze. Być może istnieje sposób, ale po prostu go nie znam. (Jeśli ktoś wie, jak wykonać takie zapytanie za pomocą DISTINCT, proszę dodać notatkę!)źródło
Oto proste podejście, które wydrukuje 2 różne czasy, które upłynęły dla każdego zapytania.
LUB spróbuj USTAWIĆ CZAS STATYSTYKI (Transact-SQL)
Po prostu wyświetla liczbę milisekund wymaganych do parsowania, kompilacji i wykonania każdej instrukcji, jak poniżej:
źródło
To nie jest reguła
Dla każdego zapytania .... spróbuj osobno oddzielić, a następnie pogrupuj według ... porównaj czas na zakończenie każdego zapytania i użyj szybszego ....
W moim projekcie czasami używam grupowania według i innych
źródło
Jeśli nie musisz wykonywać żadnych funkcji grupowych (suma, średnia itp. W przypadku, gdy chcesz dodać dane liczbowe do tabeli), użyj SELECT DISTINCT. Podejrzewam, że jest szybszy, ale nie mam na to żadnych dowodów.
W każdym razie, jeśli martwisz się szybkością, utwórz indeks w kolumnie.
źródło
SELECT DISTINCT zawsze będzie taki sam lub szybszy niż GROUP BY. W niektórych systemach (np. Oracle) może być zoptymalizowany tak, aby był taki sam jak DISTINCT dla większości zapytań. W innych (np. SQL Server) może być znacznie szybszy.
źródło
Jeśli problem na to pozwala, spróbuj z EXISTS, ponieważ jest zoptymalizowany, aby skończył się natychmiast po znalezieniu wyniku (I nie buforuj żadnej odpowiedzi), więc jeśli próbujesz po prostu znormalizować dane dla klauzuli WHERE takiej jak ta
Szybsza odpowiedź to:
Nie zawsze jest to możliwe, ale gdy będzie dostępne, zobaczysz szybszą odpowiedź.
źródło