Jef*_*ood 38 cache query sql-server sql-server-2008
我们有一个特定的 SQL Server 2008 查询(不是存储过程,而是相同的 SQL 字符串——每 5 分钟执行一次),它间歇性地缓存一个非常糟糕的查询计划。
这个查询通常在几毫秒内运行,但是这个糟糕的查询计划需要 30+ 秒。
如何从 SQL Server 2008 中手术删除一个错误的缓存查询计划,而不破坏生产数据库服务器上的整个查询缓存?
Jef*_*ood 45
我想通了一些事情
select * from sys.dm_exec_query_stats
Run Code Online (Sandbox Code Playgroud)
将显示所有缓存的查询计划。不幸的是,那里没有显示 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
Run Code Online (Sandbox Code Playgroud)
从这里开始添加一个WHERE
子句来查找我知道在查询中的 SQL 是非常简单的,然后我可以执行:
DBCC FREEPROCCACHE (plan_handle_id_goes_here)
Run Code Online (Sandbox Code Playgroud)
从查询计划缓存中删除每个查询计划。不是很容易或方便,但它似乎有效..
编辑:转储整个查询缓存也可以工作,并且没有听起来那么危险,至少在我的经验中:
DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;
Run Code Online (Sandbox Code Playgroud)
如果您知道好的计划是什么样的,只需使用计划提示即可。
您不能删除特定的缓存条目,但可以使用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
Run Code Online (Sandbox Code Playgroud)
然而,所有 SQL 计划都具有名称“SQL 计划”,这使得为 DBCC FREESYSTEMCACHE 选择正确的计划是一个……困难的选择。
更新
没关系,忘记了DBCC FREEPROCCACHE(plan_handle)
,是的,这会起作用。
归档时间: |
|
查看次数: |
52373 次 |
最近记录: |