深入學習SQL Server聚合函數算法優(yōu)化技巧
Sql server聚合函數在實際工作中應對各種需求使用的還是很廣泛的,對于聚合函數的優(yōu)化自然也就成為了一個重點,一個程序優(yōu)化的好不好直接決定了這個程序的聲明周期。Sql server聚合函數對一組值執(zhí)行計算并返回單一的值。聚合函數對一組值執(zhí)行計算,并返回單個值。除了 COUNT 以外,聚合函數都會忽略空值。 聚合函數經常與 SELECT 語句的 GROUP BY 子句一起使用。
一.寫在前面
如果有對Sql server聚合函數不熟或者忘記了的可以看我之前的一片博客。
本文中所有數據演示都是用Microsoft官方示例數據庫:Northwind,至于Northwind大家也可以在網上下載。
二.Sql server標量聚合
2.1.概念:在只包含聚合函數的 SELECT 語句列列表中指定的一種聚合函數(如 MIN()、MAX()、COUNT()、SUM() 或 AVG())。當列列表只包含聚合函數時,則結果集只具有一個行給出聚合值,該值由與 WHERE 子句謂詞相匹配的源行計算得到。
2.2.探索標量聚合:
我們先用Sql server的"包括實際的執(zhí)行計劃"來看看一個簡單的流聚合COUNT()來看看表里數據所有的行數。
再通過SET SHOWPLAN_ALL ON(關于輸出中包含的列更多信息可以在鏈接中查看)來看看有關語句執(zhí)行情況的詳細信息,并估計語句對資源的需求。
通過SET SHOWPLAN_ALL ON我們來看看COUNT()具體做了那些事情:
- 索引掃描:掃描當前表的行數
- 流計算:計算行數的數量
- 計算標量:將流計算出來的結果轉化為適當的類型。(因為索引掃描出來的結果是根據表中數據的大小決定的,如果表中數據很多的話,COUNT是int類型就會有問題,所以在最終返回的時候需要將默認類型(數值一般默認類型是Big)轉成int類型。)
- 小結:通過SET SHOWPLAN_ALL ON我們可以查看Sql server聚合函數在給我們呈現最終效果的時候,為這個效果做了些什么事情。
2.3.標量聚合優(yōu)化技巧:
我們通過兩個比較簡單的sql查詢來看看他們的區(qū)別
從上圖中可以看到,其實這兩個查詢從語句上來說沒什么太大的區(qū)別,但是為什么開銷會不一樣,一個是查詢城市一個是查詢訂單號。這是因為其實DISTINCT對于OrderID查詢來說,是沒有什么意義的,因為OrderID是主鍵,是不會有重復的。而ShipCity是會有重復的,Sql server的去重機制在去重的時候,會有一個排序的過程。這個排序還是比較消耗資源的。
對于數據量比較大的表其實不是很建議對大表排序或者對大表的某個重復次數多的字段去重運算。所以我們這里可以對ShipCity進行優(yōu)化一下。可以對ShipCity創(chuàng)建一個非聚集索引。
從上圖中可以看到,加了索引以后COUNT(DISTINCT ShipCity)的查詢變成了兩個流聚合,而沒有了排序,節(jié)省了開銷。
總結:對于標量聚合從上面的例子大家可以看到,標量聚合優(yōu)缺點很明顯:
- Sql server標量聚合優(yōu)點:算法比較簡單直觀,適合非重復值的聚合操作。Sql server標量聚合缺點:性能較差(需要排序),不適合重復值的聚合操作。
- 優(yōu)化技巧:盡量避免排序產生,將分組字(GROUP BY)段鎖定在索引覆蓋范圍內
三.Sql server哈希聚合
3.1.概念:
哈希(Hash,一般翻譯做“散列”,也有直接音譯為“哈?!钡?,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出,所以不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。)
哈希聚合的內部實現方法和哈希連接的實現機制一樣,需要哈希函數的內部運算,形成不同的哈希值,依次并行掃描數據形成聚合值。
3.2.背景:
為了解決流聚合的不足,應對大數據的操作,所以哈希聚合就誕生了。
3.3.分析:
來看看兩個簡單的查詢。
ShipCountry和CustomerID的分組查詢看上去很類似,但是為什么執(zhí)行計劃會不同呢?這是因為ShipCountry包含了大量的重復值,CustomerID重復值非常少,所以Sql server系統給ShipCountry推送的哈希聚合,而CustomerID推送的是流聚合。也就是說Sql server系統會動態(tài)的根據查詢的情況選擇合適的聚合方式。所以我們在做SQL優(yōu)化的時候不能僅根據SQL語句來優(yōu)化,還得結合具體數據分布的環(huán)境。
四.運算過程監(jiān)控指標
4.1.監(jiān)控元素:
可視化查看運行時間T-sql語句查詢時間占用內存T-sql語句查詢IO
4.2.可視化查看運行時間:
4.3.T-sql語句查詢時間:
4.4.占用內存:
4.5.T-sql語句查詢IO:
關于監(jiān)控元素還有很多,這里就列舉幾個。
SQL Server 聚合函數算法優(yōu)化技巧差不多就介紹到這里,希望對大家優(yōu)化聚合函數算法有所幫助。
相關文章
sqlserver 多表關聯時在where語句中慎用trim()方法
最近做的一個項目由于前期數據庫設計不合理,導致多表關聯的主外鍵長度設計不一致,以致過長主外鍵中過長的字段在填入相同字段時,多余部分被填入空字符。迫于無奈,就在多表關聯的where語句中使用了trim()方法。2009-09-09SQL語句實現SQL Server 2000及Sql Server 2005日志收縮(批量)
SQL語句實現SQL Server 2000及Sql Server 2005日志收縮(批量)2008-08-08SqlServer參數化查詢之where in和like實現之xml和DataTable傳參介紹
在上一篇Sql Server參數化查詢之where in和like實現詳解中介紹了在Sql Server使用參數化查詢where in的幾種實現方案,遺漏了xml和表值參數,這里做一個補充2012-05-05SQL?Server解析/操作Json格式字段數據的方法實例
SQL SERVER沒有自帶的解析json函數,需要自建一個函數(表值函數),下面這篇文章主要給大家介紹了關于SQL?Server解析/操作Json格式字段數據的相關資料,需要的朋友可以參考下2022-08-08實例理解SQL中truncate和delete的區(qū)別
這篇文章主要介紹了實例理解SQL中truncate和delete的區(qū)別,truncate和delete兩者易混,本文就為大家進行區(qū)分兩者的異同,感興趣的小伙伴們可以參考一下2016-02-02