http://www.cnblogs.com/shanksgao/p/4254942.html 高兄這篇文章很好的談論了由于數據隱式轉換造成執行計劃不準確,從而造成了死鎖。那如果在事情出現之前發現了這類潛在的風險豈不是更好?
那么我們來看一個簡單的例子,如代碼清單1所示。
1: SELECT *
2: FROM HumanResources.Employee
3: WHERE NationalIDNumber = 243322160
4:
5: SELECT *
6: FROM HumanResources.Employee
7: WHERE NationalIDNumber = '243322160'
代碼清單1.
NationalIDNumber列定義是Nvarchar,而參數第一個為INT類型,第二個為Varchar類型。那么就存在隱式轉換,由高繼偉提到的數據類型轉換優先級(https://msdn.microsoft.com/zh-cn/library/ms190309.aspx)可以看到,第一列Nvarchar和INT屬性類型,INT數據類型優先級高,需要把列NationalIDNumber轉換為INT類型,因此涉及到需要把所有該列值轉換為INT,因此只能通過掃描操作,從而影響性能。
而代碼清單1中第二個查詢,NationalIDNumber列為Nvarchar類型,而參數為varchar類型,根據數據類型優先級,需要將Varchar轉換為Navrchar,因此僅僅需要對參數進行隱式轉換,因此不影響性能。
如何在出現問題之前找到出問題的查詢?
在SQL Server中,執行計劃會被緩存起來,以便后續進行復用。SQL Server提供了一系列DMV可以查看這些執行計劃。由于執行計劃的本質是xml,因此通過XQUERY查詢特定的執行計劃變為可能。
在執行計劃中,存在隱式轉換的節點會存在類似如代碼清單2所示的字段:
1: <Convert DataType="int" Style="0" Implicit="true">
2: <ScalarOperator>
3: <Identifier>
4: <ColumnReference Database="[AdventureWorks2012]" Schema="[HumanResources]" Table="[Employee]" Column="NationalIDNumber" />
5: </Identifier>
6: </ScalarOperator>
7: </Convert>
代碼清單2.對列進行轉換的執行計劃片段
前面提到,只有對列而不是參數進行隱式轉換時,才會影響性能。而在代碼清單2中對列進行隱式轉換的執行計劃會引用具體的數據庫名稱、架構名稱、表名稱、列名稱。而對參數進行隱式轉換的僅僅是引用參數,如代碼清單3所示。
1: <Convert DataType="nvarchar" Length="8000" Style="0" Impl
新聞熱點
疑難解答