iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 26
0
自我挑戰組

全端工程師的日常挑戰三十日系列 第 26

關於清除 SQL Server 查詢快取的那些事

  • 分享至 

  • xImage
  •  

關於清除 SQL Server 查詢快取的那些事

之前的文章 試著學會看懂 SQL Server IO 統計資訊 中,有粗略地介紹 SQL Server IO 的統計資訊,其中 logical reads(邏輯讀取) 是我們用來進行效能調校的重要依據,文中也提到 cache 來源是 physical reads(實體讀取)read-ahead reads(讀取前讀取) 。在為了比較使用 memory 與使用 disk 的查詢時間差異,就得透過清除查詢 cache 來進行,接著就來看看該如何清除查詢 cache.

差異

  1. 第一次查詢(使用 disk)

    fromdisk

  2. 第二次以後查詢(使用 memory)

    frommemory

名詞介紹

  1. Clean Buffer

    data page cache 沒有修改過的

  2. Dirty Buffer

    data page cache 已修改過但未被寫入至磁碟中的部份

  3. Cold Buffer Cache

    data page 還沒載入 memory 中,需要從磁碟讀取

清除 Cache 語法

CHECKPOINT;
DBCC DROPCLEANBUFFERS;

關於 DBCC DROPCLEANBUFFERS

  • 僅清除 Clean BufferDirty Buffer無法被清除
  • 語法
    • Syntax for SQL Server
      DBCC DROPCLEANBUFFERS [ WITH NO_INFOMSGS ]

    • Syntax for Azure SQL Data Warehouse and Parallel Data Warehouse
      DBCC DROPCLEANBUFFERS ( COMPUTE | ALL ) [ WITH NO_INFOMSGS ]

參數說明

  • WITH NO_INFOMSGS

    隱藏所有參考訊息。Azure SQL Data WarehouseParallel Data Warehouse 環境下預設隱藏

  • COMPUTE

    • Azure SQL Data WarehouseParallel Data Warehouse 有效
    • 清除計算節點 cache
  • ALL

    • Azure SQL Data WarehouseParallel Data Warehouse 有效
    • 清除所有節點 cache
    • 預設值

為什麼需要 CHECKPOINT

CHECKPOINT 會將 Dirty Buffer 強制寫入 disk

我們來模擬Dirty Buffer 的情境如下

  1. 一般的 select
  • 將資料載入 cache
    SELECT * FROM [AdventureWorks2014].[Sales].[Customer]
    
  1. 檢查 cache
  • cache 有 122 筆資料
    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
    

    NORAMLCACHE

  1. 使用 DBCC DROPCLEANBUFFERS
    DBCC DROPCLEANBUFFERS
    
  2. 檢查 cache
  • 因為僅有 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
    

    cleanbufferdbcc

  1. 修改一筆資料
  • 製造出 Dirty buffer
    UPDATE [Sales].[Customer]
    SET [ModifiedDate] = GETDATE()
    WHERE [CustomerID]=1
    GO
    
  1. 一般的 select
  • 將資料載入 cache
    SELECT * FROM [AdventureWorks2014].[Sales].[Customer]
    
  1. 檢查 cache
  • cache 數量不變, 有 122 筆資料
    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
    

    update

  1. 使用 DBCC DROPCLEANBUFFERS

    DBCC DROPCLEANBUFFERS
    
  2. 檢查 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
    

    updatedbcc

  1. 使用 CHECKPOINTDBCC DROPCLEANBUFFERS

    CHECKPOINT;
    DBCC DROPCLEANBUFFERS ;
    
  2. 檢查 cache

  • CHECKPOINTDirty buffer 被寫入 disk
  • DBCC DROPCLEANBUFFERS清除 Clean buufer
  • 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
    

    ckdbcc

參考資料

  1. SQL Server: What is a COLD, DIRTY or CLEAN Buffer?
  2. DBCC DROPCLEANBUFFERS and CHECKPOINT
  3. DB_ID
  4. Checkpoint
  5. DBCC DROPCLEANBUFFERS

上一篇
怎麼讓網站在輸入網址後按 tab 就可以直接搜尋網站內容(OpenSearch)
下一篇
啟用 Windows Server 2016 的無線網路
系列文
全端工程師的日常挑戰三十日31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言