選擇以資料列版本控制為基礎的隔離等級

以資料列版本控制為基礎的隔離等級會刪除讀取作業的鎖定,來改善讀取並行。Microsoft SQL Server 引進了兩個使用資料列版本控制的交易隔離等級:

  • 讀取認可隔離的新實作,會在 READ_COMMITTED_SNAPSHOT 資料庫選項為 ON 時,使用資料列版本控制。

  • 新的隔離等級 (快照集),是在 ALLOW_SNAPSHOT_ISOLATION 資料庫選項為 ON 時啟用。

基於下列理由,建議針對大部份的應用程式使用讀取認可隔離,而非快照集隔離:

  • 它所消耗的 tempdb 空間會比快照集隔離少。

  • 它使用分散式交易,但快照集隔離不是。

  • 它可與大部份現有的應用程式一起運作,而不需任何變更。使用預設隔離等級 (讀取認可) 撰寫的應用程式可進行動態微調。不管是否使用資料列版本控制,讀取認可的行為都是由資料庫選項設定所決定,而且這個設定可以變更,不會影響到應用程式。

    [!附註]

    對於設計來相依於讀取認可隔離之封鎖行為的應用程式,開發人員可能想改變應用程式,以使用讀取認可隔離的兩種模式。除此以外,也須注意 READ_COMMITTED_SNAPSHOT 資料庫選項仍為 OFF。

  • 快照集隔離很容易發生更新衝突,而這些衝突不適用於使用資料列版本控制的讀取認可隔離。若快照集隔離下執行之交易所讀取的資料隨後會由另一個交易所修改,則快照集交易對相同資料所做的更新會導致更新衝突,交易會因而終止並回復。這不是與使用資料列版本控制之讀取認可隔離有關的問題。

使用版本控制之讀取認可隔離的使用時機

使用資料列版本控制的讀取認可隔離提供了陳述式等級的讀取一致性。執行交易內的每一個陳述式時,會取得新的資料快照集,且會對每個陳述式保持一致性,直到陳述式完成執行。發生下列情況時,會啟用使用資料列版本控制的讀取認可隔離:

  • 發生讀取器/寫入器封鎖的那一時刻,其並行好處超過了因建立及管理資料列版本所造成的負擔。

  • 應用程式會對長期執行的彙總或查詢要求絕對的精準度,即資料值必須與查詢一開始的時間點一致。

使用快照集隔離的時機

快照集隔離提供了交易等級的讀取一致性。快照集交易開始時,即會取得資料快照集,並於交易期間保持一致。發生下列情況時,可使用快照集隔離:

  • 需要開放式 (Optimistic) 並行控制。

  • 交易因更新衝突而需回復的機率不高。

  • 應用程式需要根據長期執行且需具時間點一致性的多重陳述式查詢來產生報表。快照集隔離提供了不需使用共用鎖定即可重複讀取的好處 (請參閱<並行效果>)。資料庫快照集可以提供類似功能,但必須手動實作。快照集隔離會自動為每一個快照集隔離交易提供資料庫中的最新資訊。

以資料列版本控制為基礎之隔離等級的好處

使用資料列版本控制的隔離等級提供了下列好處:

  • 讀取作業會擷取資料庫的一致快照集。

  • 讀取作業期間,SELECT 陳述式不會鎖定資料 (讀取器不會封鎖寫入器,反之亦然)。

  • 當其他交易正在更新未封鎖的資料列時,SELECT 陳述式可以存取資料列的最後認可值。

  • 減少死結數目。

  • 減少交易所需的鎖定數目,也會減少管理鎖定所需的系統負擔。

  • 較少發生鎖定擴大。

以資料列版本控制為基礎之隔離等級的成本

決定使用以資料列版本控制為基礎的隔離,需要權衡為了維護及讀取資料列版本所需增加之資源使用量,將鎖定數降至最低的並行好處。將下列與針對快照集及讀取認可隔離等級啟用資料列版本控制相關聯的成本納入考慮:

  • 當查詢所需的版本變舊,且必須掃描長的版本鏈時,可能會影響讀取效能。

  • 在資料修改期間,資料列版本控制會增加資源使用量,因為資料列版本是在 tempdb 維護。

  • 當 READ_COMMITTED_SNAPSHOT 或 ALLOW_SNAPSHOT_ISOLATION 資料庫選項為 ON 時,即使沒有交易會使用以資料列版本控制為基礎的隔離等級,特殊資料庫的更新及刪除交易也必須維護資料列版本。使用資料列版本建構資料的一致快照集包括系統資源 (CPU 及記憶體),而且可能產生 I/O 活動。因為記錄版本儲存在 tempdb 中,所以,當更多的 tempdb 分頁可儲存於記憶體中以進行資料列版本控制時,會有更好的效能,且所發出的 I/O 數目將更低。

    [!附註]

    插入資料列通常不會產生資料列版本。然而,在某些狀況下,INSERT 命令的確會產生資料列版本。例如,如果在先前刪除的資料列版本 (準刪除記錄) 未截斷時,當您於資料表中插入一個資料列,INSERT 命令將產生資料列版本。

  • tempdb 必須具有足夠磁碟空間來儲存版本。如果交易的執行時期非常長,則更新交易在那段時間產生的所有版本都將保存在 tempdb 中。如果 tempdb 將空間用完,則更新作業不會失敗,但使用資料列版本控制的讀取作業可能會失敗。

  • 資料列版本控制資訊需要 14 個位元組以加入到資料庫資料列。

  • 因維護資料列版本所需之工作的緣故,更新效能可能會變慢。在典型 OLTP 工作負載中,每一個更新只會變更資料庫中的少許資料列。在這些系統中,與兩個選項都為 OFF 的資料庫相比較,在選項為 ON 的資料庫中,其更新效能可能只慢了幾個百分點。在更新作業期間,如果有更大量資料要變更,則版本更新的效能成本可能更高。

  • 資料讀取器會面對周遊版本連結清單的額外成本。快照集越舊,在快照集隔離交易中存取它的程序就越慢。

  • 有些使用快照集隔離的更新交易可能必須回復,因為更新作業偵測到強制衝突。在使用資料列版本控制之讀取認可隔離下執行的交易不會產生更新衝突。

使用資料列版本控制的交易具有其他限制。如需詳細資訊,請參閱<使用資料列版本控制式的隔離等級>。

可從以資料列版本控制為基礎之隔離等級獲益的系統

從以資料列版本控制為基礎之隔離等級獲益的案例包括:

  • 唯讀報表及特定查詢會與正在更新資料之應用程式平行執行的系統。

  • 從其他支援類似隔離等級的關聯式資料庫系統到「Microsoft SQL Server Database Engine」的應用程式移轉。

  • 取得一致彙總 (如 AVG、COUNT 及 SUM) 或執行索引交集及索引聯結時,需要嚴格隔離等級 (如可重複的讀取或可序列化) 的系統。

  • 因讀寫爭用而具有高死結數的系統。