谁占用了我的Buffer Pool?
来源:互联网 发布:java 余弦相似度算法 编辑:程序博客网 时间:2024/05/16 15:14
我在做SQL Server 7.0技术支持的时候有客户问我,“我的SQL Server buffer pool很大,有办法知道是哪些对象吃掉我的buffer Pool内存么?比方说,能否知道是哪个数据库,哪个表,哪个index占用了buffer Pool么?”当时我没有找到这个问题的答案,但是我一直记着这个问题。直到SQL server 2005版本出现,这个问题迎刃而解。答案就是使用动态视图(DMV)sys.dm_os_buffer_descriptors。
这个DMV非常强大。根据SQL Server 联机丛书,这个视图的作用是 “返回有关 SQL Server缓冲池中当前所有数据页的信息。可以使用该视图的输出,根据数据库、对象或类型来确定缓冲池内数据库页的分布”。具体点说,这个视图能够返回buffer pool里面一个8K的data page的下列属性:
(1)该页属于哪个数据库
(2)该页属于数据库哪个文件
(3)该页的Page_ID
(4)该页的类型。可以根据这个来判断此页时索引页还是数据页
(5)该页内有多少行数据
(6)该页有多少可用空间。
(7)该页从磁盘读取以来是否修改过。
有了上面的信息,我们就可以很方便的统计出几种很有用的数据,如下。
1. Buffer Pool的内存主要是由那个数据库占了?
SELECTcount(*)*8 as cached_pages_kb,CASE database_id
WHEN 32767 THEN‘ResourceDb’
ELSE db_name(database_id)
END AS Database_name
FROMsys.dm_os_buffer_descriptors
GROUPBY db_name(database_id),database_id
ORDERBY cached_pages_kb DESC;
结果如下:
从上面的结果可以看到数据库AdventureWorks占用了大概30MB左右的缓冲池空间。
注意该DMV并不返回Buffer Pool里面有关非数据页(如执行计划的缓存等)的信息。也就是说这个DMV并没有返回Buffer Pool里面所有页面的信息。
2. 再具体一点,当前数据库的哪个表或者索引占用Pool缓冲空间最多?
SELECTcount(*)*8 AS cached_pages_kb
,obj.name ,obj.index_id,b.type_desc,b.name
FROMsys.dm_os_buffer_descriptorsAS bd
INNER JOIN
(
SELECT object_name(object_id)AS name
,index_id ,allocation_unit_id,object_id
FROM sys.allocation_unitsAS au
INNER JOINsys.partitionsAS 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,object_id
FROM sys.allocation_unitsAS au
INNER JOINsys.partitionsAS p
ON au.container_id= p.partition_id
AND au.type= 2
) AS obj
ON bd.allocation_unit_id= obj.allocation_unit_id
LEFT JOIN sys.indexes bon b.object_id= obj.object_idAND b.index_id = obj.index_id
WHERE database_id= db_id()
GROUPBY obj.name, obj.index_id,b.name,b.type_desc
ORDERBY cached_pages_kb DESC;
输出结果如下(部分):
从上面的结果可以看到表Individual在Pool内存里面缓冲最多,可能这个就是经常访问的热表,或者是比较大的表。注意Pool里面的缓冲页是经常变化的。你如果再跑一次语句,出现在头条的可能是另外一个表了。
3. Buffer Pool缓冲池里面修改过的页总数大小。这个比较容易:
SELECTcount(*)*8 as cached_pages_kb,
convert(varchar(5),convert(decimal(5,2),(100–1.0*(selectcount(*) from sys.dm_os_buffer_descriptors bwhere b.database_id=a.database_idand is_modified=0)/count(*)*100.0)))+‘%’ modified_percentage
,CASE database_id
WHEN 32767 THEN‘ResourceDb’
ELSE db_name(database_id)
END AS Database_name
FROMsys.dm_os_buffer_descriptors a
GROUPBY db_name(database_id),database_id
ORDERBY cached_pages_kb DESC;
结果:
从上面的结果可以看到,AdventureWorks数据库大概有13.84%的数据是修改过的。如果一个数据库的大部分(超过80%)是修改过的,那么这个数据库写操作非常多。反之如果这个比例接近0,那么该数据库的活动几乎是只读的。读写的比例对磁盘的安排是很重要的。当然还有其他性能数据来获得数据库读写的大概比例,这里限于篇幅就不多谈了。
- 谁占用了我的Buffer Pool?
- 谁占用了我的Buffer Pool
- 谁占用了我的Buffer Pool?
- 谁占用了我的Buffer Pool?
- 谁占用了我的Buffer Pool?
- 脚本之找出占用了Buffer Cache里大量的buffer的数据库对象
- buffer pool
- 是什么占用了我的分区
- 7 buffer pool的组织结构
- default/keep/recycle buffer pool 的区别
- mysqldump造成Buffer Pool污染的研究
- 千丝万缕的FGC与Buffer Pool
- 千丝万缕的FGC与Buffer Pool
- 千丝万缕的FGC与Buffer Pool
- KEEP Buffer Pool/recycle pool
- 如何查看谁占用了我的端口(windows、linux)
- 我的asp.net程序当前占用了多少内存?
- 我的asp.net程序当前占用了多少内存?
- 利用HttpClient发送post请求京东接口并将结果用POI导出为 Excel表格
- Android设计模式之观察者模式
- Oracle中激活scott账号
- Eclipse webservice client 调用 .net接口
- [POJ1804]Brainman
- 谁占用了我的Buffer Pool?
- api.js源码阅读学习笔记
- 关于mysql 一系列操作
- 标准模板库1(STL)——基本概念
- 在HTMl文档中使用CSS
- Oracle学习第二记
- Functions
- js事件的分类和阻止冒泡事件
- linux 遇到的问题