背景:
今天在群里發現在討論,只要sql語句有空格,就會生成另外一個執行計劃。一直沒有對這個做過check。
環境:
sql server 2008r2,northwind 數據庫 代碼導入
測試:
測試腳本1,用于查看生成的執行計劃,并清除計劃,可以看得清楚一些:
SELECT * FROM sys.dm_exec_cached_plans a CROSS APPLY sys.dm_exec_sql_text(a.plan_handle) CROSS APPLY sys.dm_exec_query_plan(a.plan_handle) SELECT * FROM sys.dm_exec_query_stats a CROSS APPLY sys.dm_exec_sql_text(a.sql_handle) CROSS APPLY sys.dm_exec_query_plan(a.plan_handle) DBCC freePRoccache
測試腳本2:
SELECT * FROM dbo.Orders WHERE OrderDate >'19900101'
測試語句3:
SELECT * FROM dbo.Orders WHERE OrderDate > '19900101'
很明顯能夠看出測試腳本2和3的區別。
刪除除了orders上除了聚集索引之外的所有索引,然后運行以上腳本,發現被參數化了,并用xml查看執行計劃:
SELECT * FROM dbo.Orders WHERE OrderDate >'19900101'SELECT * FROM dbo.Orders WHERE OrderDate > '19900101'(@1 varchar(8000))SELECT * FROM [dbo].[Orders] WHERE [OrderDate]>@1(@1 varchar(8000))SELECT * FROM [dbo].[Orders] WHERE [OrderDate]>@1
StatementOptmLevel="TRIVIAL"
之后我們隨便創建一個索引,我就用orders表中有的一個索引:
CREATE INDEX "CustomersOrders" ON "dbo"."Orders"("CustomerID")
然后再運行測試腳本,并用XML方式查看執行計劃:
SELECT * FROM dbo.Orders WHERE OrderDate >'19900101'SELECT * FROM dbo.Orders WHERE OrderDate > '19900101'SELECT * FROM dbo.Orders WHERE OrderDate > '19900101'SELECT * FROM dbo.Orders WHERE OrderDate >'19900101'
StatementOptmLevel="FULL"
結論:
這里的測試結果,是否被參數化和索引有關,和語句級別有關,如果為TRIVIAL就會執行簡單參數化,如果為FULL就不會執行簡單參數化。
但是我翻閱了一下我手頭上的資料并沒有發現,對這個現象的說明。
向知情者請教
閱讀:
文章http://blogs.msdn.com/b/psssql/archive/2013/12/04/how-simple-parameterization-work.aspx
新聞熱點
疑難解答