天天看點

模糊查詢的參數嗅探

表 t , 有複合索引 ix_t_p1_p2,p1 的篩選性不是很高。 無論加不加 option(recompile) , 執行計劃走的都是索引查找,但不加時, 因為無法準确識别參數中的%, 導緻執行計劃錯誤。 這個不用 option(recompile) 就無解了。因為畢竟是傳入值,不能直接拼SQL(擔心有注入風險)。 試過末尾添加: OPTION (OPTIMIZE FOR (@p0=N'%15673618567%',@1=N'JK523000')) 并沒有優化效果。 如果去掉複合索引,能快起來, 但擔心這個索引在其它地方有用到。 最終的方案還是加 option(recompile),。 需要注意的是, 要重制程式裡的SQL,   必須用 sp_executesql

優化前 優化後
set statistics io on
set statistics time on
declare @p0 nvarchar(8),@p1 nvarchar(13),@sql nvarchar(max)
select @p0=N'%15673618567%',@p1=N'JK523000'
SET @sql='
SELECT * FROM dbo.[t] 
WHERE 1 = 1 
AND [p0] = @p0
AND [p1] LIKE @p1
'
EXEC sp_executesql @sql
	,N'@p0 nvarchar(8),@p1 nvarchar(13)',
	@p0,@1
           
set statistics io on
set statistics time on
declare @p0 nvarchar(8),@p1 nvarchar(13),@sql nvarchar(max)
select @p0=N'%15673618567%',@p1=N'JK523000'
SET @sql='
SELECT * FROM dbo.[t] 
WHERE 1 = 1 
AND [p0] = @p0
AND [p1] LIKE @p1
option( recompile )
'
EXEC sp_executesql @sql
	,N'@p0 nvarchar(8),@p1 nvarchar(13)',
	@p0,@1
           
(1 行受影響)
表 'user_app_data'。掃描計數 1,邏輯讀取 21356 次,實體讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 實體讀取 0 次,lob 預讀 0 次。

 SQL Server 執行時間:
   CPU 時間 = 10670 毫秒,占用時間 = 10901 毫秒。

 SQL Server 執行時間:
   CPU 時間 = 10670 毫秒,占用時間 = 10902 毫秒。      
(1 行受影響)
表 'user_app_data'。掃描計數 17,邏輯讀取 22223 次,實體讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 實體讀取 0 次,lob 預讀 0 次。
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,實體讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 實體讀取 0 次,lob 預讀 0 次。
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,實體讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 實體讀取 0 次,lob 預讀 0 次。

 SQL Server 執行時間:
   CPU 時間 = 11559 毫秒,占用時間 = 772 毫秒。

 SQL Server 執行時間:
   CPU 時間 = 11575 毫秒,占用時間 = 783 毫秒。      
總時間:10.9 s 總時間:0.783 s

不加 option(recompile) 的執行計劃:

模糊查詢的參數嗅探
模糊查詢的參數嗅探

添加 option(recompile) 的執行計劃:

模糊查詢的參數嗅探
模糊查詢的參數嗅探