Sql-Server

物理讀取和預讀之間的區別

  • April 2, 2020

我試圖理解預讀讀取,但對我來說似乎有點複雜。我在網上搜尋並得到以下資訊:

閱讀頁面(Microsoft 文件):

預讀預測完成查詢執行計劃所需的數據和索引頁面,並在查詢實際使用頁面之前將它們帶入緩衝區記憶體。

從回答為什麼第一次執行查詢時 SQL Server 中的“物理讀取”小於“預讀讀取”和“邏輯讀取”?由 Huntharo 在 Stack Overflow 上發表:

物理讀取 - 查詢被阻塞,等待頁面從磁碟讀取到記憶體中以供立即使用。

Read-Ahead Read - 頁面在阻塞查詢之前被讀取,並像所有讀取一樣被讀入記憶體。掃描索引時可以進行預讀,在這種情況下,可以假定索引中的下一個葉頁是需要的,並且可以在查詢實際表示需要它們之前為它們啟動讀取。這允許磁碟在數據庫引擎檢查先前獲取的頁面的內容時處於忙碌狀態。

也許有人可以使用他們自己的解釋來澄清上述內容,因為我找不到預讀的詳細解釋。

舉個例子,看看statistics io資訊:

Table 'TestLarge'. Scan count 1, logical reads 159185, physical reads 348, read-ahead reads 159209

查詢總是從記憶體中讀取數據(邏輯讀取)。您的範例查詢掃描TestLarge表在執行期間觸及了 159,185 個 8KB 記憶體頁。

在執行期間,SQL Server 做了兩件事。

1. 它從屬於該表的頁面中讀取數據。

如果所需頁面已在記憶體中,則記錄邏輯讀取。

如果所需頁面不在記憶體中,則記錄物理讀取。

  • 頁面從持久儲存中被帶入記憶體。
  • 在此讀取完成之前,查詢將被阻止。
  • 這在您的測試查詢中發生了 348 次。
  • 當SQL Server 處理頁面(現在在記憶體中)以滿足您的查詢時,也會計算邏輯讀取。

2. 它發出預讀。

在掃描操作期間,SQL Server 每隔一段時間就會花一點時間管理預讀:

  • SQL Server 收集了一個 8KB 頁面列表,目前操作在不久的將來很可能會遇到這些頁面。您可以將其視為下一個頁面的目前掃描位置的引擎“向前看”。根據掃描的類型,它使用 IAM(分配映射)頁面或葉上方的 b-tree 級別來實現。
  • 此“前瞻”列表中尚未在記憶體中的任何頁面都將在一個或多個非同步讀取請求中傳遞給作業系統。這些被計為預讀讀取
  • 作業系統負責將頁面讀入 SQL Server 記憶體,並在讀取完成時通知 SQL Server。
  • 發出非同步讀取的 SQL Server 執行緒未被阻塞。它可以繼續掃描記憶體中的頁面,同時作業系統在單獨的執行緒上在後台獲取預讀頁面。
  • 您的測試查詢通過預讀機制將 159,209 頁讀入記憶體。

類比

想像有一本書。您僅獲得索引。這本書的其餘部分在當地圖書館。圖書館有整本書不能藉出的規定,每次進館最多只能取50頁。

您的任務是在家中按照索引中引用的頁面順序(a 到 z)組裝這本書。你不能離開家,但你有一個朋友可以代表你去圖書館。

索引中的第一個條目是“土豚”,它出現在本書的第 392 頁。

您意識到一次執行此任務的效率非常低,因此您沒有將您的朋友發送到第 392 頁的圖書館,而是按索引順序閱讀 50 個條目,並給您的朋友該頁面列表以帶到圖書館。此時您計算了 50次預讀

現在你回到處理“土豚”。您面前沒有第 392 頁,因此您必須等待,什麼也不做,直到您的朋友回來。這是物理讀取

當您的朋友到達時,您在處理第 392 頁時會計算一次邏輯讀取。

您可以從朋友帶回的其他 49 頁開始(計算每個頁面的邏輯閱讀次數),但您意識到,如果您在忙於在你面前工作。

每次您將您的朋友發送到圖書館並提供要獲取的頁面列表時,您都會計算讀次數。每次處理您面前的頁面時,您都會計算一次邏輯讀取。如果你發現自己沒有你需要的下一頁(因為你的朋友太慢了),你算上一次物理閱讀

當您和您的朋友可以有效地重疊您的活動時,整體任務會更快完成。他們可能正忙於獲取您很快將需要的頁面,而您正忙於處理您面前的頁面。當這運作良好時,您不必等待所需的下一頁,儘管您確實會花一點時間告訴您的朋友該做什麼。

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