使用动态视图: sys.dm_os_buffer_descriptors
这个视图返回一个8K data page的下列属性:
(1)该页属于哪个数据库
(2)该页属于数据库哪个文件
(3)该页的Page_ID
(4)该页的类型。可以根据这个来判断此页时索引页还是数据页
(5)该页内有多少行数据
(6)该页有多少可用空间。
(7)该页从磁盘读取以来是否修改过。
1.buffer pool的内存主要由哪个数据库占用的:
SELECT count(*)*8 as cached_pages_kb,CASE database_id WHEN 32767 THEN ‘ResourceDb’ ELSE db_name(database_id) END AS Database_nameFROM sys.dm_os_buffer_descriptorsGROUP BY db_name(database_id) ,database_idORDER BY cached_pages_kb DESC;
从上面的结果可以看到数据库AdventureWorks占用了大概30MB左右的缓冲池空间。
2.当前库哪个表占用的最多:
SELECT count(*)*8 AS cached_pages_kb ,obj.name ,obj.index_id,b.type_desc,b.nameFROM sys.dm_os_buffer_descriptors AS bd INNER JOIN ( SELECT object_name(object_id) AS name ,index_id ,allocation_unit_id,object_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,object_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 LEFT JOIN sys.indexes b on b.object_id = obj.object_id AND b.index_id = obj.index_id WHERE database_id = db_id()GROUP BY obj.name, obj.index_id ,b.name,b.type_descORDER BY cached_pages_kb DESC;
从上面的结果可以看到表Individual 在Pool内存里面缓冲最多,可能这个就是经常访问的热表,或者是比较大的表。注意Pool里面的缓冲页是经常变化的。 你如果再跑一次语句,出现在头条的可能是另外一个表了。
3.Buffer Pool缓冲池里面修改过的页总数大小:
SELECT count(*)*8 as cached_pages_kb, convert(varchar(5),convert(decimal(5,2),(100–1.0*(select count(*) from sys.dm_os_buffer_descriptors b where b.database_id=a.database_id and is_modified=0)/count(*)*100.0)))+‘%’ modified_percentage ,CASE database_id WHEN 32767 THEN ‘ResourceDb’ ELSE db_name(database_id) END AS Database_nameFROM sys.dm_os_buffer_descriptors aGROUP BY db_name(database_id) ,database_idORDER BY cached_pages_kb DESC;
从上面的结果可以看到,AdventureWorks数据库大概有13.84%的数据是修改过的。如果一个数据库的大部分(超过80%) 是修改过的,那么这个数据库写操作非常多。反之如果这个比例接近0,那么该数据库的活动几乎是只读的。
(此文为转载)