SQL去重是用DISTINCT好,還是GROUP BY好?
點擊上方SQL數據庫開發(fā),關注獲取SQL視頻教程
SQL專欄
我們知道DISTINCT可以去掉重復數據,GROUP BY在分組后也會去掉重復數據,那這兩個關鍵字在去掉重復數據時的效率,究竟誰會更高一點?
我們先看下面這個例子:
SELECT DISTINCT UnitPrice
FROM [Sales].[SalesOrderDetail]
WHERE UnitPrice>1000;執(zhí)行完之后的結果如下:

接下來,我們將這個表里的數據增大到194萬條,再重復上面的實驗。
--將表SalesOrderDetail插入到一張物理表中
SELECT * INTO Sales.Temp_SalesOrder
FROM [Sales].[SalesOrderDetail] ;
--通過新增的物理表進行自循環(huán)插入3次,將數據增加到1941072行
DECLARE @i INT;
SET @i=0
WHILE @i<4
BEGIN
--這里沒有將SalesOrderDetailID這個自增長的放在列中,是為了讓系統(tǒng)自動填充不同的數字進去,保證唯一性。
INSERT INTO Sales.Temp_SalesOrder
(SalesOrderID,CarrierTrackingNumber,OrderQty,ProductID,SpecialOfferID,
UnitPrice,UnitPriceDiscount,LineTotal,rowguid,ModifiedDate)
SELECT
SalesOrderID,CarrierTrackingNumber,OrderQty,ProductID,SpecialOfferID,
UnitPrice,UnitPriceDiscount,LineTotal,NEWID(),ModifiedDate
FROM Sales.Temp_SalesOrder
SET @i=@i+1;
END;
SELECT COUNT(1) FROM Sales.Temp_SalesOrder;(提示:可以左右滑動代碼)
將SalesOrderDetailID的自增長屬性取消掉之后,插入1000條自身的數據,這樣我們就可以得到1000條重復的SalesOrderDetailID,相比1942072條記錄占比很小了
如下圖,將自增長標識的是換成否后即可插入了。

INSERT INTO sales.Temp_Salesorder
SELECT TOP 1000 * FROM sales.Temp_Salesorder;數據插入完整后,我們在將上一講的內容重復一下,看看效果如何?
A.在沒建索引的情況下,我們只查詢UnitPrice這一列
SELECT UnitPrice FROM Sales.Temp_SalesOrder ;我們看一下執(zhí)行情況:

接下來是鑒證奇跡的時刻了,我們加DISTINCT在UnitPrice前面試試
SELECT ?DISTINCT ?UnitPrice FROM sales.Temp_Salesorder;
和之前的實驗結果一致,在執(zhí)行時間沒有多大差別的情況下,分析時間成倍的減少了。
B.當SalesOrderDetailID取消掉自增長屬性后就和普通列一樣了。
我們來重復上面的步驟:
SELECT ? SalesOrderDetailID FROM sales.Temp_Salesorder執(zhí)行完后結果如下:

與上面的UnitPrice沒使用DISTINCT情況基本一致。
然后我們給SalesOrderDetailID加上DISTINCT后會怎么樣呢?
SELECT DISTINCT ?SalesOrderDetailID
FROM sales.Temp_Salesorder我們可以看到如下執(zhí)行情況:

從上圖可以看到,DISTINCT已經排除了1000條記錄,但是在執(zhí)行時花的時間比沒加DISTINCT更久了。
通過上述兩個實驗,我們可以得出這樣一條結論:在重復量比較高的表中,使用DISTINCT可以有效提高查詢效率,而在重復量比較低的表中,使用DISTINCT會嚴重降低查詢效率。所以并不是所有的DISTINCT都是降低效率的,當然你得提前判斷數據的重復量。
2.GROUP BY與DISTINCT去掉重復數據的對比
GROUP BY與DISTINCT類似,經常會有一些針對這兩個哪個效率高的爭議,今天我們就將這兩個在不同重復數據量的效率作下對比。
A.重復數據量多的情況下,對UnitPrice進行去重
SELECT ?DISTINCT ?UnitPrice FROM sales.Temp_Salesorder;
SELECT ?UnitPrice FROM sales.Temp_Salesorder GROUP BY UnitPrice;
將上述兩條語句一起執(zhí)行,結果如下:

可以看出兩條語句對應的執(zhí)行時間GROUP BY比DISTINCT效率高一點點。
B.重復數據量少的情況下,對SalesOrderDetailID進行去重
SELECT ?DISTINCT SalesOrderDetailID FROM sales.Temp_Salesorder
SELECT ? SalesOrderDetailID FROM sales.Temp_Salesorder
GROUP BY SalesOrderDetailID
也是同時執(zhí)行上述兩條語句,其結果如下:

作者對上述語句同時執(zhí)行多次,針對重復量多的UnitPrice,GROUP BY總的處理效率比DISTINCT高一點點,但是針對重復量低的SalesOrderDetailID,DISTINCT就比GROUP BY快一點了,而如果隨著整體數據量的增加,效果會越來越明顯。
今天的內容就講到這里,小伙伴可以動手嘗試一下。如有不明白的可以在下方留言一起探討。
——End——
后臺回復關鍵字:1024,獲取一份精心整理的技術干貨 后臺回復關鍵字:進群,帶你進入高手如云的交流群。 推薦閱讀
這是一個能學到技術的公眾號,歡迎關注
