[转载]已经不再使用的表为什么数据页还在SQLServer的内存缓存中 - JentleWang - 博客园

[转载]已经不再使用的表为什么数据页还在SQLServer的内存缓存中 – JentleWang – 博客园.

1. 问题发现

 

在学习内存调优时,使用如下代码,查询目前内存缓冲区中生产数据库的每个对象缓存页计数

SELECT count(*)AS cached_pages_count
,name ,index_id
FROM sys.dm_os_buffer_descriptors AS bd
INNER JOIN
(
SELECT object_name(object_id) AS name
,index_id ,allocation_unit_id
FROM sys.allocation_units AS au
INNER JOIN sys.partitions AS p
ON au.container_id = p.hobt_id
AND (au.type = 1 OR au.type = 3)
UNION ALL
SELECT object_name(object_id) AS name
,index_id, allocation_unit_id
FROM sys.allocation_units AS au
INNER JOIN sys.partitions AS p
ON au.container_id = p.partition_id
AND au.type = 2
) AS obj
ON bd.allocation_unit_id = obj.allocation_unit_id
WHERE database_id = db_id()
GROUP BY name, index_id
ORDER BY cached_pages_count DESC;

 

发现前段应用程序已经不再使用的表,数据页缓存数排在首位,而且页数非常之 多。这张表是之前用来作为数据统计分析的计算报表,后来上了数据仓库以及BI系统后,这张表就废弃掉了。但为什么内存中还是缓存这么多数据页?现在系统的 内存并非是足够大,大到可以缓存整个数据库的数据页面,所以,感觉这些不再使用的数据页面应该被置换出内存

 

2.问题分析

 

 为了验证这种表的使用情况,使用如下语句查询表的索引使用情况

 

1
2
3
SELECT
FROM sys.dm_db_index_usage_stats ddius
WHERE ddius.object_id = OBJECT_ID('t_rpt_office_shop_data')

 

发现索引的user_scan 等确实为0,代表自上次服务启动以来,应用程序没用提交过对这个表的查询。

 

  但发现system_scan不为0,而且last_system_scan的日期为凌晨。

 

  所以猜想是不是凌晨的数据库维护计划中有导致system_scan的操作

 

  继续查看维护计划,发现果真有一个任务–更新统计信息任务,而且扫描类型是完全扫描

 

3.问题原因

 

所以,问题是由每天早上的更新统计信息任务造成,因为执行完全扫描,相当于每天凌晨对这个表执行了一次全表扫描,此时会将数据页加载到内存缓冲区中。而且我发现凌晨这段时间内存的页面生命周期基本接近为0,估计也是这个造成的。

 

4.问题处理

 

以下是我的处理方式,大家指正下~

 

  1. 将维护计划中的更新统计信息步骤删除掉,第二天发现内存缓冲的对象数据页计数基本和预测一致。
  2. 将不在使用的表进行数据压缩,减少磁盘空间的占用
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏