Sql-Server

事務隔離級別 - 在大型表上讀取已送出和選擇

  • January 13, 2017

我正在嘗試解決報告中的問題,並想知道以下情況是否可能。我有一個 548GB 的​​表格,有些報告有時會選擇 5 年的數據,這些數據可能幾乎是整個表格。該表具有非唯一聚集索引。

我閱讀了有關讀取送出的隔離級別並正在對其進行測試以查看它在選擇期間如何鎖定表,據我了解,它看起來像是放置了一系列共享頁面鎖。獲取共享頁鎖、讀取頁、釋放共享頁鎖、移動到下一頁等。

如果上述情況屬實,並且假設查詢正在執行聚集索引掃描,那麼它如何處理已讀取過去的表開頭的插入。我所說的表開頭的意思是,由於該表具有聚集索引,並且如果插入了較低值的索引 id 記錄,則必須對其進行排序,因此需要將其插入到聚集的葉級別的起始半部分指數。

通常,儲存引擎有兩個選項來執行聚集索引掃描:分配順序掃描或索引順序掃描。對於分配順序掃描,儲存引擎按文件順序讀取數據。在您的場景中,這可能會導致插入的數據出現在第一個查詢中。對於索引順序掃描,儲存引擎以鍊錶順序讀取數據。在您的場景中,插入的新數據不會顯示在第一個查詢中。即使包含新行的頁面拆分,也不會讀取新頁面。

儲存引擎根據查詢的要求和隔離級別來決定是分配順序掃描還是索引順序掃描。例如,對於要求數據按順序排列的查詢,索引順序掃描是正確的選擇。對於具有表鎖且不需要數據有序的查詢,分配順序掃描是正確的選擇。具體來說,當滿足以下所有條件時,您最終將獲得不安全類別的分配順序(掃描可以返回多次出現的行或在發生頁面拆分時跳過行):

  • 查詢在讀未送出隔離級別下執行
  • 允許對數據進行更改(查詢未使用表鎖)
  • 計劃顯示 Index Scan, Ordered: false (查詢不需要對數據進行排序)
  • 索引大小大於 64 頁。

在您的範例中,您有一個已送出讀的隔離級別。您也沒有對聚集索引掃描查詢使用表鎖,因為第二個會話能夠插入一行。因此,儲存引擎將執行索引順序掃描品種的掃描。插入的新數據不會顯示在執行掃描的第一個查詢中。

我的資料來源是 Itzik Ben-Gan、Dejan Sarka、Adam Machanic 和 Kevin Farlee 的 T-SQL Querying 第 65-69 頁。

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