文章出處

前言

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

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

技術準備

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

一、聯合運算符

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

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

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

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

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

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

我們來看一下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調優系列基礎篇(常用運算符總結)

 

如果您看了本篇博客,覺得對您有所收獲,請不要吝嗇您的“推薦”。

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()