1. 程式人生 > 實用技巧 >SQL SERVER-儲存引數嗅探(parameter sniffing)

SQL SERVER-儲存引數嗅探(parameter sniffing)

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