Answers:
我弄明白了几件事
select * from sys.dm_exec_query_stats
将显示所有缓存的查询计划。不幸的是,那里没有显示SQL文本。
但是,您可以将SQL文本加入计划,如下所示:
select plan_handle, creation_time, last_execution_time, execution_count, qt.text
FROM
sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text (qs.[sql_handle]) AS qt
从这里开始,添加一个WHERE
子句以查找我知道在查询中的SQL是很简单的,然后可以执行:
DBCC FREEPROCCACHE (plan_handle_id_goes_here)
从查询计划缓存中删除每个查询计划。并非完全简单或方便,但它似乎可以工作。
编辑:至少以我的经验,转储整个查询缓存也可以,并且比听起来听起来危险的少。
DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;
如果您知道好的计划是什么样子,请使用计划提示。
您无法删除特定的缓存条目,但是可以使用清理整个缓存池DBCC FREESYSTEMCACHE(cachename/poolname)
。
如果你有计划句柄(由你可以得到一个坏的查询计划的缓存名称sys.dm_exec_requests.plan_handle执行过程中麻烦的session_id,或从sys.dm_exec_query_stats动态管理执行后的):
select ce.name
from sys.dm_exec_cached_plans cp
join sys.dm_os_memory_cache_entries ce on cp.memory_object_address = ce.memory_object_address
where cp.plan_handle = @bad_plan
但是,所有SQL计划的名称都为“ SQL计划”,这使得为DBCC FREESYSTEMCACHE选择正确的计划变得非常困难。
更新资料
没关系,忘记了DBCC FREEPROCCACHE(plan_handle)
,是的,它将起作用。
sys.dm_exec_cached_plans
没有plan_handle
来自from的条目,那意味着什么sys.dm_exec_requests
?
该FREEPROCCACHE解决方案是好的,但这样做的更直接的方式是使用OPTION(RECOMPILE)在您的SQL字符串(你提到这不是一个SP),这告诉引擎它的单次使用计划,因为可能你怀疑有参数嗅探,或者您的统计信息在每次运行中都大不相同,因此您怀疑它存在错误的缓存计划问题。
DECLARE @SQL NVARCHAR(4000)
SELECT @SQL = 'SELECT * FROM Table WHERE Column LIKE @NAME OPTION (RECOMPILE)'
EXEC sp_executesql @SQL, N'@NAME varchar(15)', 'MyName'