SQL Server調優系列基礎篇(聯合運算符總結)

前言html

上兩篇文章咱們介紹了查看查詢計劃的方式,以及一些經常使用的鏈接運算符的優化技巧,本篇咱們總結聯合運算符的使用方式和優化技巧。算法

廢話少說,直接進入本篇的主題。post

技術準備性能

基於SQL Server2008R2版本,利用微軟的一個更簡潔的案例庫(Northwind)進行解析。大數據

1、聯合運算符優化

所謂的聯合運算符,其實應用最多的就兩種:UNION ALL和UNION。url

這兩個運算符用法很簡單,前者是將兩個數據集結果合併,後者則是合併後進行去重操做,若是有過寫T-SQL語句的碼農都不會陌生。spa

咱們來分析下這兩個運算符在執行計劃中的顯示,舉個例子線程

SELECT FirstName+N''+LastName,City,Country FROM Employees
UNION ALL
SELECT ContactName,City,Country FROM Customers

就是上面這個圖標了,這就是UNION ALL聯合運算符的圖標。3d

這個聯合運算符很簡單的操做,將兩個數據集合掃描完經過聯合將結果彙總。

咱們來看一下UNION 這個運算符,例子以下

select City,Country from Employees
UNION
SELECT City,Country FROM Customers

咱們能夠看到,UNION 運算符是在串聯運算符以後發生了一個Distinct Sort排序操做,通過這個操做會將結果集合中的重複值去掉。

咱們一直強調:大數據表的排序是一個很是耗資源的動做!

因此,到這裏咱們已經找到了可優化的選項,去掉排序,或者更改排序方式。

替換掉Distinct Sort排序操做的方式就是哈序聚合。Distinct Sort排序操做須要的內存和去除重複以前數據集合的數據量成正比,而哈希聚合須要的內存則是和去除重複以後的結果集成正比!

因此若是數據行中重複值不少,那麼相比而言經過哈希聚合所消耗的內存會少。

咱們來舉個例子

select ShipCountry from Orders
UNION
SELECT ShipCountry FROM Orders

這個例子其實沒啥用處,這裏就是爲了演示,咱們來看一下結果

咱們知道,這張表裏這個ShipCountry是存在大面積重複值的,因此採用了哈希匹配來去重操做是最優的方式。

其實,相比哈希匹配鏈接還有一種更輕量級的去重的鏈接方式:合併鏈接

上一篇我已經分析了這個鏈接方法,用於兩個數據集的鏈接方式,這裏其實相似,應用前都必須先將原結果集合排序!

咱們知道優化的方式能夠採用創建索引來提升排序速度。

咱們來重現這種去重方式,咱們新建一個表,而後創建索引,代碼以下

--新建表
SELECT EmployeeID,FirstName+N' '+LastName AS ContactName,City,Country
INTO NewEmployees
FROM Employees
GO
--添加索引
ALTER TABLE NewEmployees ADD CONSTRAINT PK_NewEmployees PRIMARY KEY(EmployeeID)
CREATE INDEX ContactName ON NewEmployees(ContactName)
CREATE INDEX ContactName ON CUSTOMERS(ContactName)
GO
--新建查詢,這裏必定要加上一個顯示的Order by才能出現合併鏈接去重
SELECT ContactName FROM NewEmployees
UNION ALL
SELECT ContactName FROM Customers
ORDER BY ContactName

 

咱們採用索引掃描的方式能夠避免顯式的排序操做。

咱們將UNION ALL改爲UNION,該操做將會對兩個數據集進行去重操做。

--新建查詢,這裏必定要加上一個顯示的Order by才能出現合併鏈接去重
SELECT ContactName FROM NewEmployees
UNION 
SELECT ContactName FROM Customers
ORDER BY ContactName

這裏咱們知道UNION操做會對結果進行去重操做,上面應用了流聚合操做,流聚合通常應用於分組操做中,固然這裏用它進行了分組去重。

 

在咱們實際的應用環境中,最經常使用的方式仍是合併鏈接,可是有一種狀況最適合哈希鏈接,那就是一個小表和大表進行聯合操做,尤爲適合哪一種大表中存在大量重複值的狀況下。

哈希算法真是個好東西!

 

參考文獻

結語

此篇文章先到此吧,簡短一點,便於理解掌握,本篇主要介紹了查詢計劃中的聯合操做運算符,下一篇咱們分析SQL Server中的並行運算,在多核超線程雲集的今天,來看SQL Server如何利用並行運算來最大化的利用現有硬件資源提高性能,有興趣可提早關注,關於SQL Server性能調優的內容涉及面很廣,後續文章中依次展開分析。

 

SQL Server這個軟件一旦深刻進去,你會發現它真的很是深,基本能夠用深不見底來描述,若是想研究裏面的性能調優這塊,能夠關注本系列內容,咱們一塊兒研究!

並且到如今還有不少人對SQL Server這套產品有誤解,或者說觀點有待糾正,之前就遇到過客戶直接當我面大談神馬SQL Server導入數據一多就宕機了....

神馬SQL Server只能作小數據量的應用...神馬不如Oracle云云....!!!

還有一部分童鞋單純的認爲SQL Server是小兒科,沒啥技術含量...簡單的很....

關於這些觀點,我不想吐槽啥,我只想讓那些真正瞭解SQL Server的朋友一塊兒來爲SQL Server證實點什麼。

 

文章最後給出上一篇的鏈接

SQL Server調優系列基礎篇

SQL Server調優系列基礎篇(經常使用運算符總結)

 

若是您看了本篇博客,以爲對您有所收穫,請不要吝嗇您的「推薦」。

相關文章
相關標籤/搜索