Sql-Server

NCCI 中的 Lob 邏輯讀取和 lob 預讀

  • September 5, 2019

我有一個具有以下結構的測試表。

CREATE TABLE [dbo].[DW_test](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[CourtCaseID] [int] NOT NULL,
[ActionID] [int] NOT NULL,
PRIMARY KEY CLUSTERED([ID] ASC)

接下來,我使用以下腳本在我的表中填充了大約 4.7 億條記錄。

insert into DW_test
--select count(*)
--from (
select top 1000000 abs(checksum(newid())) % 100000 + 1 a, abs(checksum(newid())) % 10 + 1 b
from sys.all_objects
cross join sys.all_objects a
cross join sys.all_objects b
cross join sys.all_objects c
cross join sys.all_objects d
cross join sys.all_objects e
cross join sys.all_objects f
cross join sys.all_objects g
--) t
GO

該腳本執行了大約 470 次,在表中生成了 4.7 億條記錄,並在該表上創建了 NCCI。

CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_test1] ON [dbo].[DW_test]
(
   [CourtCaseID],
   [ActionID]
)

接下來我測試簡單的查詢來計算表中的記錄。

DBCC DROPCLEANBUFFERS
GO
select COUNT_BIG(*)
from DW_test 

如果我轉身SET STATISTICS IO ON,我會得到以下結果

帶冷記憶體

表’DW_test’。掃描計數 25,邏輯讀取 3,物理讀取 0,預讀讀取 0,lob 邏輯讀取 469697,lob 物理讀取 1,lob 預讀讀取 1877324。

表’DW_test’。段讀取 453,段跳過 0。

表“工作台”。掃描計數 0,邏輯讀取 0,物理讀取 0,預讀讀取 0,lob 邏輯讀取 0,lob 物理讀取 0,lob 預讀讀取 0。

帶暖記憶體

表’DW_test’。掃描計數 25,邏輯讀取 3,物理讀取 0,預讀讀取 0,lob 邏輯讀取 229248,lob 物理讀取 0,lob 預讀讀取 0。

表’DW_test’。段讀取 453,段跳過 0。

表“工作台”。掃描計數 0,邏輯讀取 0,物理讀取 0,預讀讀取 0,lob 邏輯讀取 0,lob 物理讀取 0,lob 預讀讀取 0。

我知道 1 次邏輯讀取是在查詢執行期間從緩衝池讀取的單個數據頁,而 1 次物理讀取是從磁碟讀取的單個數據頁。RedGate 告訴我們預讀是:

這個數字告訴我們 SQL Server 的“預讀”機制滿足了多少物理讀取。這與物理讀取直接相關,因此如果沒有物理讀取,則預讀讀取將為 0。

就我而言,我正在處理 lob 邏輯、物理和預讀。我想了解這個數字在我的特定情況下意味著什麼。

如果表有大約 4.7 億條記錄,怎麼可能只有 1 個 lob 物理讀取和冷記憶體?

lob 頁面的總數怎麼可能從冷記憶體中的約 230 萬減少到熱記憶體中的約 220k?

如果表有大約 4.7 億條記錄,怎麼可能只有 1 個 lob 物理讀取和冷記憶體?

有 1 次 LOB 物理讀取和 1,877,324 次預讀。預讀仍然是物理讀取,只是提前執行(預取)。Redgate 的報價不正確。

lob 頁面的總數怎麼可能從冷記憶體中的約 230 萬減少到熱記憶體中的約 220k?

邏輯讀取計算記憶體中頁面被觸摸的次數。從 469,697(冷記憶體)減少到 229,248(暖記憶體)。我對此沒有完整的解釋,但這可能部分是因為列儲存數據連續記憶體在單獨的列儲存對像池中,而不是一般的頁面大小的緩衝池中。

預讀從 b 樹的上層讀取頁面以在掃描之前辨識要讀取的頁面,這也可能導致不同數量的“額外”邏輯讀取,具體取決於儲存系統的時序和特性. 列儲存索引在持久儲存上具有 b 樹結構。

另一個因素是並行性(您的測試似乎是在 DOP 24 執行的),因為來自不同執行緒的重疊請求會導致額外的邏輯讀取。如果您使用OPTION (MAXDOP 1).

列儲存的內部儲存詳細資訊沒有詳細記錄,通常的 DMV 也沒有完全支持。在這個階段,我想說冷記憶體和熱記憶體情況之間的讀取減少的最好解釋是磁碟儲存和記憶體(記憶體)儲存之間的差異。

列儲存數據(字典和段)儲存在磁碟上的 LOB 中,但出於性能原因並沒有以相同的格式保存在記憶體中。因為它們是不同的東西,所以不能僅僅將邏輯讀取添加到物理讀取中以獲得有意義的結果。

“如果表有大約 4.7 億條記錄,怎麼可能只有 1 個 lob 物理讀取和冷記憶體?”

因為其他物理讀取由預讀(LOB 類型)提供服務。也許那篇 RedGate 文章讓您感到困惑,但如果您將某個範圍(例如)用作預讀 (RA),那麼您將看不到任何物理讀取。收集物理讀取統計資訊的執行緒在記憶體中找到了這些頁面,因此它們沒有被累積到物理讀取計數器中。

我們遇到的另一種情況是經典的緩衝區記憶體命中率 perfmon 計數器。RA 讀取對這個值沒有貢獻,因此您可能有負載和物理 I/O 負載,但在 BCHR 中仍然接近 100。

“lob 頁面的總數怎麼可能從冷記憶體中的約 230 萬減少到熱記憶體中的約 220k?”

我的猜測是第一個啟動了自動創建統計資訊。

引用自:https://dba.stackexchange.com/questions/246617