为什么一个计划会从缓存中删除?

最近有人问我,我们是否能知道为什么要从缓存中删除一个计划。如果你读了这个博客,你知道我接下来要说什么。我检查了扩展事件,实际上有两个不同的事件将告诉我们有关从缓存中删除的计划的信息;sp_cache_Remove和Query_Cache_Remove_STATISTISTICS。让我们谈谈这些是如何工作的。

从缓存中移除

为了让我们看到所有的活动,我创建了一个扩展事件会话,它捕获的不仅仅是两个事件:

 
CREATE EVENT SESSION PlanCacheRemoval
 
ON SERVER
 
ADD EVENT sqlserver.query_cache_removal_statistics
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.rpc_completed
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.rpc_starting
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sp_cache_hit
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sp_cache_insert
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sp_cache_miss
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sp_cache_remove
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sp_statement_completed
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sp_statement_starting
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sql_batch_completed
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017')),
 
ADD EVENT sqlserver.sql_batch_starting
 
(WHERE (sqlserver.database_name = N'AdventureWorks2017'))
 
ADD TARGET package0.event_file
 
(SET filename = N'C:\PerfData\PlanCacheRemoval.xel')
 
WITH (TRACK_CAUSALITY = ON);
 

我正在捕获批处理开始和完成,RPC开始和完成,最后是所有的缓存语句,点击,错过,插入和删除。第一次运行过程时,结果可能如下所示:

因为这是第一次运行这个过程,所以我们得到一个sp_cache_想念事件,因为查询不存在。然后我们看到SQL_Batch_START(我正在从SSM运行这个过程)。下面是计划被添加到缓存时的sp_cache_INSERT事件。然后,我们看到所有的语句都在运行,加上重新编译,因为我为了好玩而抛入了一个临时表(这样您就可以看到发生了什么)。

在此之后,计划就在缓存中。现在,让我们做一些事情,使计划从缓存中删除。我会修改程序。这导致下列事件:

您将注意到序列中的第二个语句是Batch_Text中的“Create or AL.”。那是我在修改程序。下一个事件是sp_cache_Remove。它将Remove_方法显示为“Compplan Remove”。这是以自动方式从缓存中删除的计划。接下来的三个事件都是用于查询_Cache_Remove_STATISTICS的。

他们是什么。

这些是从DMV中删除的语句级统计信息。没错,我们可以观察到从系统中删除的信息以及缓存中的计划。

手动从缓存中删除

我们可以很容易地看到自动过程从缓存中删除计划。如果我们使用数据库作用域配置来清除该数据库的过程缓存(注意:您希望至少运行一次过程,以便将其删除),会发生什么情况:

您可以再次看到正在使用的“Compplan Remove”方法。当我们使用DBCCFREEPROCCACHE对缓存进行核弹时会发生什么情况:

有数百个查询_缓存_删除_STATISTISTICS事件,然后是多个不同的“.刷新“事件”以删除所有内容。

结语

虽然我没有深入了解如何从缓存中删除对象的所有细节,但您可以看到,可以了解如何使用扩展事件将对象从缓存中移出的方式和原因。通过因果关系跟踪将所有事件组合在一起,可以更容易地看到这些事件发生的顺序。

猜你喜欢

转载自www.cnblogs.com/ybyqi/p/9851163.html