Percentage of Data and Index Page Use In Buffer Pool


Below is a query you can use to find out how much of the pages in the memory buffer pool actually contain data.  SQL Server does not read parts of  8 KB pages into memory, so if the page fill is poor based on poor table and index design, then you may be holding up a bunch of memory with nothing in it.

SELECT DB_NAME(DATABASE_ID) Database_Name,
        PAGE_TYPE,
                COUNT(DATABASE_ID) / 128 as MB_USED,
SUM(cast(FREE_space_in_bytes as bigint))/(1024.0)/(1024.0) as MB_EMPTY,
(SUM(cast(FREE_space_in_bytes as bigint))/(1024.0)/(1024.0)/ (COUNT(DATABASE_ID) / 128)) * 100.0 as Percentage_Empty
FROM Sys.dm_os_buffer_descriptors
WHERE database_ID = --<YOUR DATABASE ID>
and page_type in ('data_page', 'index_page')
GROUP BY DB_NAME(database_id), page_type;


Example Results:


The source for the buffer pool data is the DMV sys.dm_os_buffer_descriptors.

The function DB_NAME() with take the DATABASE_ID and return the name of the database.  

There are several types of pages in SQL Server but for this we are only looking for data_page and index_page as you can see in the predicate page_type in ('data_page', 'index_page'). 

Each record is for an 8KB page, so we get the MB_USED by dividing the count of 8KB pages by 128.  

In order to get the MB_EMPTY we take the sum of free_space_in_bytes which as the name implies returns the free space in bytes. Casting the result to bigint ensures there is no data type overflow. Dividing by 1024 twice will convert the bytes to megabytes.

Finally, using the same logic for the MB_EMPTY and dividing by the logic used for MB_USED give the percentage of free space by page.

One of the faults with this script is the possibility of dividing by zero.  In my example I ensured that would not happen by limiting the results to a specific database I knew would always return results greater than zero.

As you can see from my example there is plenty of room for improvement in the data pages.  If you have control over the design of the database you could look for really wide tables and further normalize the tables.  Otherwise, if you don't have control, you can look into the use of data compression with the hopes of getting more data onto a single page.    

Popular posts from this blog

Power BI Report Server: "An Error Has Occurred" or Power BI Report Server: "My Power BI Report is Coming up Blank" or Power BI Report Server: "401 and 403” Errors From Nowhere

SQL SERVER 2017: STRING_AGG

Dynamic Label Positions With SSRS