Query for information about pages in buffer cache
Fivi Panopoulou - Sotiris Karras
Για να πάρουμε πληροφορίες για τις σελίδες που βρίσκονται στην buffer pool του SQL Server, χρησιμοποιούμε το dmv sys.dm_os_buffer_descriptors. Το dmv αυτό από μόνο του όμως, δεν μας λέει σε ποια tables ή views ανήκουν οι συγκεκριμένες σελίδες αυτές. Για να φτάσουμε σε αυτή την πληροφορία, θα πάμε να πάρουμε πληροφορίες από το
sys.allocation_units, αφού έχουμε το allocation_unit_id. Το sys.allocation_units μας δίνει τις στηλες type και container_id οι οποίες μας ενδιαφέρουν για να φτάσουμε στο object στο οποίο ανήκουν οι σελίδες μας. Για κάθε type ή σημασία του και η αντίστοιχη σημασία του contrainer_id είναι όπως φαίνεται στον ακόλουθο πίνακα:
type |
type description |
container_id |
0 |
Dropped |
Allocation unit marked for deferred drop |
1 |
In-row data |
sys.partitions.hobt_id |
2 |
LOB data |
sys.partitions.partition_id |
3 |
Row-overflow data |
sys.partitions.hobt_id |
Έχοντας αυτή την πληροφορία μπορούμε μέσω του sys.partitions να πάρουμε το object_id του object στο οποίο αντιστοιχεί κάθε page. Έτσι λοιπόν με το παρακάτω query μαζεύουμε χρήσιμες πληροφορίες για τα pages στο buffer pool.
SELECT
BufferDesc.page_id AS [Page Id]
,BufferDesc.page_type AS [Page Type]
,(CASE WHEN BufferDesc.is_modified = 1 THEN 'Dirty' ELSE 'Clean' END) AS [Page Status]
,BufferDesc.page_level AS [Page Level]
,((8192 - BufferDesc.free_space_in_bytes)/8192.00)*100 AS [Page Used Space%]
,CAST (BufferDesc.read_microsec / (1000.0) AS DECIMAL(6,2)) AS [Time to read page to buffer (ms)]
,DB_NAME(BufferDesc.database_id) AS [Database Name]
,(CASE
WHEN Part.object_id IS NULL THEN OBJECT_NAME(HoBt.object_id)
WHEN HoBt.object_id IS NULL THEN OBJECT_NAME(Part.object_id)
END) AS [Table/View Name]
FROM sys.dm_os_buffer_descriptors AS BufferDesc
INNER JOIN sys.allocation_units AS Alloc
ON Alloc.allocation_unit_id = BufferDesc.allocation_unit_id
LEFT OUTER JOIN sys.PARTITIONS AS HoBt
ON (Alloc.container_id = HoBt.hobt_id AND (Alloc.type = 1 OR Alloc.type = 3))
LEFT OUTER JOIN sys.PARTITIONS AS Part
ON (Alloc.container_id = Part.partition_id AND (Alloc.type =2))
WHERE ((Part.object_id IS NULL AND OBJECTPROPERTY(HoBt.object_id, 'IsMSShipped') = 0)
OR (HoBt.object_id IS NULL AND OBJECTPROPERTY(Part.object_id, 'IsMSShipped') = 0));
Διευκρινήσεις για τις στήλες που μας επιστρέφει το παραπάνω query
Page Status: μας δείχνει αν στην σελίδα αυτή έχουν γίνει αλλαγές αφού την διαβάσαμε από τον δίσκο, οπότε την χαρακτηρίζουμε ως "Dirty", ή δεν έχει υποστεί αλλαγές και είναι "Clean"
Page Level: Index level της σελίδας
Page Used Space%: το ποσοστό επι τοις εκατό στο οποίο η σελίδα είναι γεμάτη. Την πληροφορία αυτή την βρίσκουμε μεσώ της free_space_in_bytes στήλης του sys.dm_os_buffer_descriptors
Time to read page to buffer (ms): ο χρόνος που χρειάζεται να διαβαστεί από τον δίσκο και να πάει στην buffer cache το I/O block του οποίου μέρος είναι η κάθε σελίδα.