1. 程式人生 > >常用執行計劃操作符

常用執行計劃操作符

空間 比較 書簽 額外 發生 掃描 效率 lis 操作

一、數據訪問操作符

1、SCAN操作符:掃描操作主要分為3種

Table Scan:當針對一個表(沒有聚集索引、堆表)執行一個查詢語句時,

此時將會做全表掃描操作(如果有where子句,則先執行全表掃描操作,然後在針對結果集做Filter操作)

示例:

技術分享

Cluster Index Scan:聚集索引掃描,表中所有的數據都存在於聚集索引的葉節點中,因此聚集索引掃描相當於將整個表中的數據都取出。

技術分享

Non-clustered Index Scan:當查詢的字段都被包含在一個覆蓋索引中的情況下,查詢優化器會優先使用Index Scan來查找這些數據,

因為非聚集索引比聚集索引占用的空間小,I/O成本更低。

示例:在Test表上創建一個覆蓋索引  

Create index idx_Name_IdentityNo_Sex_Age_Job_LiveAddress on Test(Name) INCLUDE(Sex,IdentityNo,Age,LiveAddress,Job)

查詢SQL

SELECT Name,Sex,IdentityNo,Age,LiveAddress,Job FROM dbo.Test

執行計劃如下

技術分享

2、SEEK操作符:

根據索引的不同可以分為:聚集索引查詢非聚集索引查找

聚集索引查找發生在對聚集索引字段(一般情況下都是主鍵字段)進行where過濾的情況下

技術分享

非聚集索引查找

發生在對非聚集索引字段進行where過濾的情況下

技術分享

3、Bookmark Lookup操作符:書簽查找發生在非聚集索引的語句中,用於查詢不包含在當前索引中的字段

一般優化手段是將額外的字段包含在一個Include索引

技術分享

二、連接操作符

1、Nested Loop

一般外表為小表(一般小於10000數據),較大數據表做為內表。循環嵌套連接查找內部循環表的次數等於外部循環的行數,

因此最好對內表的相應的字段上建索引,否則內表將需要做多次的全表掃描,性能有可能會產生影響。

技術分享

2、Merge Join

一般而言,當輸入兩端有序的情況下,適用Merge Join效率會比較高。

示例:b表中的ProductID上有建索引,此時輸入兩端都處於有序狀態

SELECT  b.SalesOrderDetailID,a.Name FROM Production.Product a
JOIN Sales.SalesOrderDetail b ON a.ProductID=b.ProductID

技術分享

如果輸入兩端處於無序的情況下,強制使用Merge Join連接,則將會額外多出排序操作以確保輸入兩端有序

SELECT  b.SalesOrderDetailID,a.Name FROM Production.Product a
INNER MERGE JOIN Sales.SalesOrderDetail b ON a.ListPrice=b.UnitPrice
WHERE a.ListPrice>5

技術分享

3、Hash Join

連接表數據量較大,並且輸入兩端無序(連接列無索引)時,查詢優化器將優先使用Hash Join連接方式

SELECT  b.SalesOrderDetailID,a.Name FROM Production.Product a
INNER JOIN Sales.SalesOrderDetail b ON a.ListPrice=b.UnitPrice

技術分享

三、聚合操作符

聚合操作分兩類:Stream Aggregate(流聚合)和Hash Aggregate(哈希聚合)

1、流聚合:

流聚合中又分兩種:一種是不包含GROUP BY子句的也稱為標量聚合,另外一種是包含GROUP BY子句聚合

標量聚合示例:

技術分享

Group By聚合示例:

技術分享

由執行計劃可以看出,針對Group By字段上建立合適的索引,將省去額外的Sort操作。

2、哈希聚合:

當數據量較大,且輸入端數據無排序的情況下,查詢優化器一般會使用哈希聚合(叠代器名稱為:Hash Match)

示例:

SELECT UnitPrice,COUNT(1) FROM Sales.SalesOrderDetail
GROUP BY UnitPrice

技術分享

常用執行計劃操作符