SQL SERVER-儲存引數嗅探(parameter sniffing)
阿新 • • 發佈:2020-08-26
Q
儲存過程會快取執行計劃,進行復用,但是可能資料分佈極不均勻,導致快取的計劃不適合一些引數,當帶入這些特殊引數按以前的計劃執行時,出現了效能問題。
以下SQL查詢儲存的執行計劃,可以找出有問題的SQL
--檢視執行時間,次數,平均時間 SELECT d.object_id , d.database_id , OBJECT_NAME(object_id, database_id) 'proc name' , d.cached_time , d.last_execution_time , d.total_elapsed_time , d.total_elapsed_time/ d.execution_count AS [avg_elapsed_time] , d.last_elapsed_time , d.execution_count FROM sys.dm_exec_procedure_stats AS d WHERE OBJECT_NAME(object_id, database_id) = 'usp_xx' ORDER BY [total_worker_time] DESC; --檢視執行計劃 SELECT d.object_id , DB_NAME(d.database_id) DBName ,OBJECT_NAME(object_id, database_id) 'SPName' , d.cached_time , d.last_execution_time , d.total_elapsed_time/1000000 AS total_elapsed_time, d.total_elapsed_time / d.execution_count/1000000 AS [avg_elapsed_time] , d.last_elapsed_time/1000000 AS last_elapsed_time, d.execution_count , d.total_physical_reads , d.last_physical_reads , d.total_logical_writes , d.last_logical_reads , et.text SQLText , eqp.query_plan executionplan FROM sys.dm_exec_procedure_stats AS d CROSS APPLY sys.dm_exec_sql_text(d.sql_handle) et CROSS APPLY sys.dm_exec_query_plan(d.plan_handle) eqp WHERE OBJECT_NAME(object_id, database_id) = 'usp_xx' ORDER BY [total_worker_time] DESC;
A
解決方法:
在問題的SQL後加option,這2種都可以,
INSERT INTO [dbo].[jjjj] VALUES(13) OPTION (OPTIMIZE FOR UNKNOWN) INSERT INTO [dbo].[jjjj] VALUES(13) OPTION (RECOMPILE)
使用哪一種原則如下:
1:執行不頻繁的儲存過程,使用OPTION(RECOMPILE)要優先與OPTION (OPTIMIZE FOR UNKNOWN)
2:執行頻繁的儲存過程,使用OPTION (OPTIMIZE FOR UNKNOWN)要優先於OPTION(RECOMPILE)
3:資料分佈傾斜的厲害的情況下,優先使用OPTION(RECOMPILE)
4:使用OPTION (OPTIMIZE FOR UNKNOWN)會生成一個穩定、統一的執行計劃,如果這個執行計劃的效率基本能滿足使用者需求,那麼優先使用OPTION (OPTIMIZE FOR UNKNOWN)
參考資料:https://www.cnblogs.com/kerrycode/p/9684192.html
在儲存中加入with recompile,但是這種每次執行都要重新編譯,所以不建議使用
ALTER PROCEDURE [dbo].[usp_ddd] with recompile AS BEGIN SELECT @@SERVERNAME END