更新統計資料會導致查詢重新編譯,updating statistics causes queries to recompile

更新統計資料可確保查詢使用最新的統計資料進行編譯。不過,更新統計資料會導致查詢重新編譯。

我們建議您不要太頻繁地更新統計資料,因為改善查詢計畫與重新編譯查詢所花費的時間之間具有效

能權衡取捨。

上一段的敘述說明是MSDN中描述當統計值更新後會造成相關Query重新編譯執行計畫,下面我們做一個

小實驗來測試看看是否是如此呢?

 

這次測試是採用Northwind資料庫,我們先執行一個簡單的語法,語法如下

select * from orders o
inner join [dbo].[Order Details] od on od.OrderID=o.OrderID
inner join [dbo].[Products] p on p.ProductID=od.ProductID
where o.orderid=10248

 

我們可以由下圖看到,Select出來的資料筆數有3筆。

 

完成上述的語法執行後,我們來看看該Query的執行計畫狀態,語法如下

SELECT UseCounts, Cacheobjtype, Objtype,qs.plan_generation_num, TEXT, query_plan
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
inner join sys.dm_exec_query_stats qs on qs.plan_handle=cp.plan_handle
where text like '%10248%'

 

執行完上述語法後我們可以透過下圖紅色圈選處瞭解,我們透過UseCounts欄位可知道該執行計畫

已被使用過一次,透過plan_generation_num欄位可以知道該Query執行計畫編譯次數為1次。

plan_generation_num : A sequence number that can be used to distinguish between instances of plans after a recompile.

 

此時我們再執行一次Query的語法,執行完後可以從下圖看見UseCounts數已經變為2,

而plan_generation_num則還是1次。

 

接下來我透過大量的塞入資料,讓SQL會自動更新統計資料,語法如下,我塞入4800多筆資料。

declare @i int
set @i=78;
while @i<4900
begin
	insert into [Northwind].[dbo].[Order Details] values(10248,@i,14,12,0);
	set @i+=1;
end

 

塞入4800多筆資料後,我們再執行一次該Query。從下圖可以看到筆數已超過剛剛執行時的3筆資料。

 

最後我們再看看該Query的執行計畫的相關統計是否有不同變化。如下圖所示,執行次數變為3次。而

該Query執行計畫的編譯次數也變為2次。

 

透過簡單的測試,我們可以知道統計資料的更新,會導致相關的Query重新尋找編譯執行計畫。

 

參考資料來源 : 更新統計資料   sys.dm_exec_query_stats

我是ROCK

rockchang@mails.fju.edu.tw