2009-01-09 13 views
37

Dlaczego ktoś użyłby grupy jako odróżniającej, gdy nie ma żadnych agregacji w zapytaniu?Grupa sql w odróżnieniu od

Czy ktoś zna tę grupę w porównaniu do różnych czynników wydajności w MySQL i SQL Server. Zgaduję, że SQL Server ma lepszy optymalizator i może być bliski odpowiednikowi, ale w MySQL oczekuję znacznej przewagi wydajności.

Jestem zainteresowany odpowiedziami na dba.

EDYTOWANIE:

Stanowisko Billa jest interesujące, ale nie dotyczy. Pozwól mi być bardziej szczegółowe ...

select a, b, c 
from table x 
group by a, b,c 

kontra

select distinct a,b,c 
from table x 
+1

ten jest ściśle związany z, ale nie dokładnie takie same Pytanie: http://stackoverflow.com/questions/164319/is-there-any-difference-between-group-by-and-distinct –

+0

Najprawdopodobniej dlatego, że nie wiedzieli, o co im chodzi. Jeśli jesteś pewien, że wiedzieli, o co im chodzi, to podejrzewam, że istnieje różnica w sposobie, w jaki wartości NULL są traktowane pomiędzy dwoma - od ręki, nie wiem co. –

+0

Myślę, że odpowiedź jest tak prosta, jak - pisarz nie wiedział o różnych (co jest zaskakujące, ponieważ myślałem, że był pro). – mson

Odpowiedz

18

Trochę (BARDZO małe) dane empiryczne z MS SQL Server, na kilku losowych tabelach z naszego DB.

Dla wzoru:

SELECT col1, col2 FROM table GROUP BY col1, col2 

i

SELECT DISTINCT col1, col2 FROM table 

Kiedy nie ma wskaźnik pokrycia dla zapytania oba sposoby produkowane następujący plan zapytania:

|--Sort(DISTINCT ORDER BY:([table].[col1] ASC, [table].[col2] ASC)) 
    |--Clustered Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index])) 

a kiedy nie był indeksem pokrywającym, oba wyprodukowane:

więc z tej bardzo małej próbki SQL Server na pewno traktuje oba takie same.

+0

dzięki za potwierdzenie - domyśliłbym się, że wielcy sprzedawcy zoptymalizowali to, ale też zgaduję, że MySQL tego nie zrobił. – mson

2

Zarówno będzie generować ten sam plan kwerendy w MS SQL Server .... Jeśli masz MS SQL Server można po prostu włączyć rzeczywista plan wykonania, aby zobaczyć co jest lepsze dla Twoich potrzeb ...

Proszę spojrzeć na te stanowiska:

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/

http://www.sqlmag.com/Article/ArticleID/24282/sql_server_24282.html

+0

używanie grupy zamiast wyraźnych zapachów takich jak newb. istnieje o wiele więcej składni bez zysku. także - nie masz żadnych danych - tylko pogłoski z bloga innego użytkownika. – mson

28

GROUP BY grupy maps wierszy jednym rzędzie, za wyraźną wartość w konkretnych kolumn, które nawet nie muszą być koniecznie w select-listy.

SELECT b, c, d FROM table1 GROUP BY a; 

To zapytanie SQL jest legalny (korekcja : tylko w MySQL; w rzeczywistości nie jest to standardowy SQL i nie jest obsługiwany przez innych producentów). MySQL akceptuje to i wie, że wiesz, co robisz, wybierając w łatwy sposób b, i d, ponieważ są one functional dependencies z a.

Jednak Microsoft SQL Server i inne marki nie zezwalają na to zapytanie, ponieważ nie mogą łatwo określić zależności funkcjonalnych. edytuj: Zamiast tego, standardowy SQL wymaga przestrzegania reguły o pojedynczej wartości, tj. Każda kolumna na liście wyboru musi być albo nazwana w klauzuli GROUP BY, albo też być argumentem dla ustawionej funkcji.

Podczas gdy DISTINCT zawsze wyświetla wszystkie kolumny na liście wyboru i tylko te kolumny. Jest to błędne przekonanie, że DISTINCT pozwala określić kolumny:

SELECT DISTINCT(a), b, c FROM table1; 

Pomimo nawiasach dokonujących DISTINCT wyglądają jak wywołania funkcji, to nie jest. Jest to opcja zapytania, a odrębna wartość w dowolnym z trzech pól listy wyboru prowadzi do odrębnego wiersza w wyniku zapytania. Jedno z wyrażeń na tej liście wyboru zawiera nawiasy okrągłe, ale nie ma to wpływu na wynik.

+1

interesujące, ale nieistotne. odpowiadasz na pytanie dotyczące popełniania błędów w zapytaniach. również, nie sądzę, że jest to standard ansi, aby zaakceptować takie zapytanie, jak pozujesz. jeśli w ogóle, jest to błąd w mysql - inni główni dostawcy nie obsługują tej "funkcji" – mson

+0

Wyławianie tematu, ale drugie zapytanie Bill daje (SELECT DISTINCT (a) ...) jest całkowicie poprawne ANSI SQL-92. Nawiasy są właściwie nieistotne; możesz wykonać SELECT a, (b), c FROM table1, i to jest poprawne. Po prostu dlatego, że jest to pierwszy parametr, który wygląda na to, że "a" jest parametrem DISTINCT. – Cowan

+1

@mson: Masz rację! Sprawdziłem to w moim "SQL-99 Complete, naprawdę" i stwierdziłem, że wymuszanie reguły pojedynczej wartości jest standardowym SQL i RDBMS, który go nie wymusza (np. MySQL) nie jest zgodny ze standardowym SQL. –

0

Jeśli naprawdę szukasz różnych wartości, wyrazisty sprawia, że ​​kod źródłowy jest bardziej czytelny (np. Jeśli jest częścią procedury przechowywanej) Jeśli piszę zapytania ad-hoc, zwykle zacznę od grupy, nawet jeśli nie mam żadnych agregacji, ponieważ często będę je nakładał.

+0

Robię to samo co ty, ale w innym kierunku. zaczynam od wybrania odrębnego i przejdź do grupy, jeśli jest ku temu powód. Nie staram się optymalizować wszystkiego, ale jeśli mogę zapamiętać kilka zasad dotyczących tego, co jest szybsze i czystsze, podążam za nimi. grupa według jest nieco niechlujnie-2 klauzule – mson

3

W MySQL odkryłem, że używanie GROUP BY ma często lepszą wydajność niż DISTINCT.

Wykonywanie "WYBORU WYBORU WYBORU" pokazuje "Używanie gdzie; Używanie tymczasowego" MySQL tworzy tymczasową tabelę.

vs o "explain SELECT A, B, C, gdzie T1, T2 T2.A = grupa T1.A przez" pokazuje tylko "za pomocą gdzie"

+0

zawsze powinieneś sprawdzić EXPLAIN danego zapytania. Dzisiaj miałem zapytanie, które brzmiało "KORZYSTAJĄC z tymczasowego, KORZYSTAJĄC z plików" z grupą, ale tylko "KORZYSTAJĄC tymczasowo" z DISTINCT. dlatego wariant DISTINCT był 4 razy szybszy. (mysql 5.7) – staabm