2009-01-09 168 views
37

爲什麼在查詢中沒有完成聚合時,有人會使用group而不是distinct?sql group by versus distinct

此外,是否有人知道在MySQL和SQL Server中的性能考慮因素而非性別因素。我猜SQL Server有一個更好的優化器,他們可能接近於同等的地位,但在MySQL中,我期望明顯的性能優勢。

我對dba答案很感興趣。

編輯:

比爾的帖子很有趣,但不適用。讓我更具體...

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

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

這是密切相關的,但不是完全一樣的問題在於,http://stackoverflow.com/questions/164319/is-there-any-difference-between-group-by-and-distinct – 2009-01-09 02:38:20

+0

很可能是因爲他們不知道他們是怎麼回事。如果你確定他們知道他們是怎麼回事的話,那麼我會懷疑在這兩者之間處理NULL值的方式是有區別的,但我不能認爲是什麼。 – 2009-01-09 05:31:02

+0

我認爲答案很簡單 - 作者不知道獨特(這是令人驚訝的,因爲我認爲他是專業人士)。 – mson 2009-01-09 09:59:10

回答

18

來自我們數據庫的一對隨機表中的一些(非常少)來自MS SQL Server的經驗數據。

有關模式:

SELECT col1, col2 FROM table GROUP BY col1, col2 

SELECT DISTINCT col1, col2 FROM table 

當有此查詢的覆蓋索引,這兩種方式產生了以下查詢計劃:

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

當有是一個覆蓋指數,都產生:

|--Stream Aggregate(GROUP BY:([table].[col1], [table].[col2])) 
    |--Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]), ORDERED FORWARD) 

所以從那個非常小的樣本SQL Server當然對待都一樣。

2

雙方將產生MS SQL Server的同一查詢計劃....如果你有MS SQL服務器,你可以只允許將實際執行計劃,看看哪一個是你需要更好的...

請看看那些帖子:

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

使用group而不是像newb這樣的獨特氣味。沒有任何收益的語法有很多。還有 - 你沒有任何指標 - 只是從別人的博客傳聞。 – mson 2009-01-09 01:48:50

28

GROUP BY行的圖組一行,每個不同的價值具體列,甚至不一定要在選擇列表中。

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

這個查詢是合法的SQL(修正:只在MySQL中,實際上它不是標準的SQL,而不是其他品牌的支持)。 MySQL接受它,並相信您知道自己在做什麼,以明確的方式選擇bcd,因爲它們是functional dependenciesa

但是,Microsoft SQL Server和其他品牌不允許此查詢,因爲它無法輕鬆確定功能依賴關係。 編輯:相反,標準SQL要求您遵循單值規則,即選擇列表中的每個列必須在GROUP BY子句中命名,否則必須是設置函數的參數。

DISTINCT總是查看選擇列表中的所有列,只查看那些列。這是一個普遍的誤解,認爲DISTINCT允許您指定的列:

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

儘管使DISTINCT看起來像函數調用的括號,事實並非如此。這是一個查詢選項,並且在選擇列表的三個字段中的任何一個字段中的獨特值都將導致查詢結果中的不同行。這個選擇列表中的其中一個表達式帶有括號,但這不會影響結果。

+1

有趣但無關緊要。您正在回答有關在查詢中犯錯的問題。另外,我認爲接受這樣的查詢並不符合ansi標準。如果有的話,這是一個在MySQL的錯誤 - 其他主要供應商不支持這個'功能' – mson 2009-01-09 03:11:03

+0

脫離主題,但第二個查詢比爾給(SELECT DISTINCT(a)...)是完全有效的ANSI SQL-92。括號實際上是不相關的;你可以做SELECT a,(b),c FROM table1,這是有效的。只是因爲它是它看起來像的第一個參數,'a'是一個DISTINCT的參數。 – Cowan 2009-01-09 04:26:45

0

如果你真的在尋找不同的值,這個獨特的特性使得源代碼更具可讀性(就好像它是存儲過程的一部分一樣)如果我正在編寫臨時查詢,我通常會從group by開始,即使我沒有聚合,因爲我經常會把它們放在上面。

3

在MySQL中,我發現使用GROUP BY的性能往往比DISTINCT更好。

執行「EXPLAIN SELECT DISTINCT」顯示「Using where; Using temporary」MySQL將創建一個臨時表。

Vs的 「從T1,T2 EXPLAIN SELECT A,B,C,其中T2.A = T1.A GROUP BY一個」 只是顯示 「使用,其中」