之前的文章 試著學會看懂 SQL Server IO 統計資訊 中,有粗略地介紹 SQL Server IO 的統計資訊,其中 logical reads(邏輯讀取)
是我們用來進行效能調校的重要依據,文中也提到 cache 來源是 physical reads(實體讀取)
、read-ahead reads(讀取前讀取)
。在為了比較使用 memory 與使用 disk 的查詢時間差異,就得透過清除查詢 cache 來進行,接著就來看看該如何清除查詢 cache.
第一次查詢(使用 disk)
第二次以後查詢(使用 memory)
Clean Buffer
data page cache 沒有修改過的
Dirty Buffer
data page cache 已修改過但未被寫入至磁碟中的部份
Cold Buffer Cache
data page 還沒載入 memory 中,需要從磁碟讀取
CHECKPOINT;
DBCC DROPCLEANBUFFERS;
DBCC DROPCLEANBUFFERS
Clean Buffer
,Dirty Buffer
無法被清除Syntax for SQL Server
DBCC DROPCLEANBUFFERS [ WITH NO_INFOMSGS ]
Syntax for Azure SQL Data Warehouse and Parallel Data WarehouseDBCC DROPCLEANBUFFERS ( COMPUTE | ALL ) [ WITH NO_INFOMSGS ]
WITH NO_INFOMSGS
隱藏所有參考訊息。
Azure SQL Data Warehouse
跟Parallel Data Warehouse
環境下預設隱藏
COMPUTE
Azure SQL Data Warehouse
跟 Parallel Data Warehouse
有效ALL
Azure SQL Data Warehouse
跟 Parallel Data Warehouse
有效CHECKPOINT
CHECKPOINT
會將Dirty Buffer
強制寫入 disk
我們來模擬Dirty Buffer
的情境如下
SELECT * FROM [AdventureWorks2014].[Sales].[Customer]
select sysObj.name,*
from sys.dm_os_buffer_descriptors bufferDescriptors
INNER JOIN sys.allocation_units AllocUnits ON bufferDescriptors.allocation_unit_id = AllocUnits.allocation_unit_id
INNER JOIN sys.partitions Partitions ON AllocUnits.container_id = Partitions.hobt_id
INNER JOIN sys.objects sysObj ON Partitions.object_id = sysObj.object_id
WHERE bufferDescriptors.database_id = DB_ID()
AND sysObj.is_ms_shipped = 0
DBCC DROPCLEANBUFFERS
DBCC DROPCLEANBUFFERS
Clean Buffer
,所以可以全部清除
select sysObj.name,*
from sys.dm_os_buffer_descriptors bufferDescriptors
INNER JOIN sys.allocation_units AllocUnits ON bufferDescriptors.allocation_unit_id = AllocUnits.allocation_unit_id
INNER JOIN sys.partitions Partitions ON AllocUnits.container_id = Partitions.hobt_id
INNER JOIN sys.objects sysObj ON Partitions.object_id = sysObj.object_id
WHERE bufferDescriptors.database_id = DB_ID()
AND sysObj.is_ms_shipped = 0
Dirty buffer
UPDATE [Sales].[Customer]
SET [ModifiedDate] = GETDATE()
WHERE [CustomerID]=1
GO
SELECT * FROM [AdventureWorks2014].[Sales].[Customer]
select sysObj.name,*
from sys.dm_os_buffer_descriptors bufferDescriptors
INNER JOIN sys.allocation_units AllocUnits ON bufferDescriptors.allocation_unit_id = AllocUnits.allocation_unit_id
INNER JOIN sys.partitions Partitions ON AllocUnits.container_id = Partitions.hobt_id
INNER JOIN sys.objects sysObj ON Partitions.object_id = sysObj.object_id
WHERE bufferDescriptors.database_id = DB_ID()
AND sysObj.is_ms_shipped = 0
使用 DBCC DROPCLEANBUFFERS
DBCC DROPCLEANBUFFERS
檢查 cache
Dirty Buffer
,cache 無法全部清除
select sysObj.name,*
from sys.dm_os_buffer_descriptors bufferDescriptors
INNER JOIN sys.allocation_units AllocUnits ON bufferDescriptors.allocation_unit_id = AllocUnits.allocation_unit_id
INNER JOIN sys.partitions Partitions ON AllocUnits.container_id = Partitions.hobt_id
INNER JOIN sys.objects sysObj ON Partitions.object_id = sysObj.object_id
WHERE bufferDescriptors.database_id = DB_ID()
AND sysObj.is_ms_shipped = 0
使用 CHECKPOINT
及 DBCC DROPCLEANBUFFERS
CHECKPOINT;
DBCC DROPCLEANBUFFERS ;
檢查 cache
CHECKPOINT
將 Dirty buffer
被寫入 diskDBCC DROPCLEANBUFFERS
清除 Clean buufer
select sysObj.name,*
from sys.dm_os_buffer_descriptors bufferDescriptors
INNER JOIN sys.allocation_units AllocUnits ON bufferDescriptors.allocation_unit_id = AllocUnits.allocation_unit_id
INNER JOIN sys.partitions Partitions ON AllocUnits.container_id = Partitions.hobt_id
INNER JOIN sys.objects sysObj ON Partitions.object_id = sysObj.object_id
WHERE bufferDescriptors.database_id = DB_ID()
AND sysObj.is_ms_shipped = 0