即使在禁用預讀和清除緩衝區之後,為什麼還有邏輯讀?
當所有數據頁都應僅在磁碟中時,我必須找到在 SQL-SERVER 2016 中執行查詢所需的總時間。為此,我使用以下命令清除了 SQL-SERVER 中的所有緩衝區:
DBCC FREEPROCCACHE WITH NO_INFOMSGS GO DBCC DROPCLEANBUFFERS GO DBCC FREESESSIONCACHE GO DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL GO DBCC FLUSHPROCINDB (@dbId) GO
在此之後我再次發現那裡有邏輯讀取,然後我了解了 Read-Ahead ,所以我通過跟踪標誌禁用了預讀
DBCC TRACEON(652,-1) GO
還有預取標誌
DBCC TRACEON(8744,-1) GO
現在我仍然有邏輯讀取,但是物理讀取比清除緩衝區要高得多。有什麼辦法可以實現0邏輯讀,還是我對邏輯讀的理解有誤?
請指導我完成,我是 SQL-SERVER 世界的新手
在查詢執行期間從緩衝區高速記憶體中檢索單個頁面時計算邏輯讀取。無論是否使用物理或預讀來記憶體頁面,或者該頁面是否已存在於緩衝區記憶體中,都會計算此值。因此,邏輯讀取是查詢執行期間記憶體中實際訪問頁面的次數的度量。
當儲存引擎從儲存中讀取一個或多個頁面時,會計算一次物理讀取,因為請求的頁面尚未在記憶體中。這不包括通過預讀掃描完成的物理 IO。
當儲存引擎在順序掃描期間從儲存中讀取一個或多個完整擴展區(每個擴展區為 8 個連續頁面)時,計為預讀讀取。預讀會積極地將數據預取到記憶體中,以便在查詢需要時頁面可能已經被記憶體。預讀掃描讀取的範圍數因 SQL Server 版本和版本以及碎片而異。我已經看到在使用最新 SQL Server 版本的 Enterprise Edition 中進行掃描期間,使用單個 scatter-gather IO 一次讀取多達 4MB 的預讀掃描。
請注意,SQL Server儲存引擎的行為與冷記憶體不同(例如,在重新啟動或 之後
DBCC DROPCLEANBUFFERS
)。當記憶體尚未預熱時(滿足緩衝區管理器的目標頁面),儲存引擎執行完整的 64K 範圍讀取而不是單個 8K 頁面讀取來將頁面讀取到記憶體中。這比其他方式更快地加熱記憶體。出於查詢和索引調整的目的,我更喜歡關注邏輯讀取而不是物理讀取,因為這是對查詢執行工作的更好衡量。數據是否被記憶體只是偶然的。使用冷記憶體測試更多的是衡量儲存性能而不是查詢性能,恕我直言,並且不能代表在使用熱記憶體的生產工作負載下會發生什麼。
總會有邏輯讀取。SQL Server 從不直接從磁碟向您返回數據。如果您需要的頁面已經在緩衝池中,則進行邏輯讀取。如果不是,則將其移入緩衝池,然後還有邏輯讀取。您將始終從記憶體中獲得讀取。
另外,我不明白你測試的重點。難道只是末日分析?如果您只是在從空記憶體開始時測量返回數據的時間,為什麼不只是測量時間呢?你為什麼擔心邏輯/物理讀取?如果您不相信您發出的命令會清除計劃記憶體/緩衝池,您可以在發出查詢之前通過 DMV 檢查這些內容。