查詢計劃Hash和查詢Hash

查詢計劃hash和查詢hash

  在SQL Server 2008中引入的圍繞執行計劃和緩衝的新功能被稱爲查詢計劃hash和查詢hash。這是使用針對查詢或查詢計劃的算法來生成二進制hash值的二進制對象。算法

  能夠從sys.dm_exec_query_stats或sys.dm_exec_requests檢索查詢計劃hash和查詢hash。雖然這是確認查詢及其計劃的一種機制,可是hash值不是惟一的。不類似的查詢可能得出相同的hash,因此不能將其做爲備份主鍵。sql

  分別建立兩個查詢以下:服務器

SELECT * FROM PersonHunderThousand INNER JOIN Province
ON PersonHunderThousand.PId = Province.Id
WHERE PersonHunderThousand.Name = '郎徊刺'
AND Province.Name = '廣東'

SELECT* from PersonHunderThousand INNER JOIN Province 
ON PersonHunderThousand.PId = Province.Id
where PersonHunderThousand.Name = '習笑'
AND Province.Name = '廣東'

  兩個查詢僅僅是from和where大小寫不通以及第一個參數不一樣,設計成INNER JOIN和兩個條件稍微複雜點是爲了防止簡單參數化生成參數計劃,再執行如下查詢:工具

SELECT t.text,s.execution_count,s.query_hash,s.query_plan_hash
FROM sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_sql_text(s.plan_handle) t

  看到輸出以下:性能

  

  從上面的輸入圖能夠看到,建立了兩個不一樣的計劃,由於這些查詢不是參數化的,它們太複雜以至不能考慮簡單參數化,而且強制參數化關閉。這兩個計劃有相同的hash值,由於它們不一樣的方面只是傳遞的值。大小寫的差異對查詢hash或查詢計劃hash來講可有可無。spa

  可是若是修改SELECT改成只返回一列:設計

SELECT PersonHunderThousand.ID FROM PersonHunderThousand INNER JOIN Province 
ON PersonHunderThousand.PId = Province.Id
WHERE PersonHunderThousand.Name = '郎徊刺' 
AND Province.Name ='廣東'

  該查詢生成了一個新的計劃。code

  儘管查詢的基本結構相同,返回列中的修改也足以改變查詢hash和查詢計劃hash值。對象

  由於數據分佈和索引中的不一樣可能致使相同的查詢得出兩個不一樣的計劃,query_hash可能相同,_query_plan_hash可能不一樣blog

  

  另外,有時就算只傳入一個參數,可是由於根據統計,不一樣的參數的執行計劃不一樣,也會建立兩個計劃:

SELECT * FROM PersonTenThousand 
WHERE Id = 1/100 --倘若傳入的參數會生成不一樣的執行計劃,那麼也會建立不一樣的計劃

  查詢計劃hash和查詢hash值對於跟蹤徹底不一樣的查詢之間的常見問題多是有用的工具,可是正如所見,它們不能再每種可能性中獲得一組精確的信息。它們增長了又一種確認查詢性能可能低下的場所的有用工具。能夠在將查詢部署到生產環境仲以後捕捉查詢的query_plan_hash,而後隨時觀察以瞭解其是否因數據變化而變化。由此,能夠引用sys.dm_exec_query_stats根據計劃跟蹤集合的查詢狀態,可是要記住,這些集合的數據在服務器重啓時會重置。

相關文章
相關標籤/搜索