What's swimming in your bufferpool?
Published Mar 23 2019 05:01 AM 530 Views
Microsoft
First published on MSDN on May 18, 2007

When doing a performance investigation a useful thing to do is look at what data is present in the buffer pool.  This can be used to analyze impact of running a query on the state of data pages in buffer pool. By collecting the pre and post picture of buffer pool, you can see the cost of running a query in terms of physical IOs that happened. You may argue that this can be done by looking at statistics IO output; however if you are running a series of queries and want to see a consolidated data and not data about individual queries, this query is a great help.



The contents of the buffer pool can also reveal which pages are accessed most frequently by your applications and often reflect the actual I/O that is happening.  How can frequently access pages in memory also cause disk I/O?   When lots of different objects are accessed overtime the proportion of data in the buffer pool reflects the frequency of access. This happens because data pages of infrequently accessed objects get kicked out of main memory over time.



If you are not familiar with the buffer pool, it contains several types of objects such as data pages and plans.  For more information on the buffer pool see Buffer Management http://msdn2.microsoft.com/en-us/library/aa337525.aspx



The following query can be used to look at the contents of the buffer pool -



select


count(*)as cached_pages_count,


obj.name as objectname,


ind.name as indexname,


obj.index_id as indexid


from sys.dm_os_buffer_descriptors as bd


inner join


(


select       object_id as objectid,


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_id as objectid,


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


left outer join sys.indexes ind


on  obj.objectid = ind.object_id


and  obj.index_id = ind.index_id


where bd.database_id = db_id()


and bd.page_type in ('data_page', 'index_page')


group by obj.name, ind.name, obj.index_id


order by cached_pages_count desc



An example of what it returns –



1.       Run following command to remove all clean data pages from the buffer pool –  (DO NOT TRY THIS COMMAND ON PRODUCTION MACHINES)



DBCC DROPCLEANBUFFERS



Running buffer pool analysis query had following results –



cached_pages_count ObjectName         IndexName              IndexId


------------------ ------------------ ---------------------- -----------


15                 sysobjvalues       clst                   1


3                  sysallocunits      clust                  1


2                  syshobtcolumns     clust                  1


2                  sysrowsetcolumns   clust                  1


2                  sysrowsets         clust                  1


2                  sysschobjs         clst                   1




2.       Run the following query on AdventureWorks database –



select * from Person.Address


where city like 'Bothell'



This is going to read from disk the data pages needed to execute the query. Run the buffer pool analysis query again to see the change.



cached_pages_count ObjectName         IndexName              IndexId


------------------ ------------------ ---------------------- -----------


278                Address            PK_Address_AddressID   1


15                 sysobjvalues       clst                   1


4                  sysmultiobjrefs    clst                   1


3                  sysallocunits      clust                  1


2                  syshobtcolumns     clust                  1


2                  sysrowsetcolumns   clust                  1




As you can see now there are data pages in buffer pool from the Address table. Additionally since only clustered index pages for Address table are present, no other indexes were used in the query.



Another tool which can help in this case is DBCC MEMORYSTATUS output. The advantage of the query in the entry is nice result set which can be stored in a temp table.




Authors:


Tony Voellm

Gaurav Bindlish
Version history
Last update:
‎Mar 23 2019 05:01 AM
Updated by: