<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SQL去重是用DISTINCT好,還是GROUP BY好?

          共 535字,需瀏覽 2分鐘

           ·

          2020-09-21 08:16

          點擊上方SQL數據庫開發(fā),關注獲取SQL視頻教程


          SQL專欄

          SQL基礎知識匯總

          SQL高級知識匯總


          我們知道DISTINCT可以去掉重復數據,GROUP BY在分組后也會去掉重復數據,那這兩個關鍵字在去掉重復數據時的效率,究竟誰會更高一點?

          1.使用DISTINCT去掉重復數據

          我們先看下面這個例子:

          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,獲取一份精心整理的技術干貨
          后臺回復關鍵字:進群,帶你進入高手如云的交流群。
          推薦閱讀
          這是一個能學到技術的公眾號,歡迎關注
          點擊「閱讀原文」了解SQL訓練營

          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线亚洲黄色电影 | 国产精品久久午夜夜伦鲁鲁 | 国产第一页影院 | 日本a免费在线观看 | 欧美成人视频18 |