DB2 並發度受限通常源於:讀寫互斥(隔離級別過高)、鎖持有時間過長/範圍過大、無索引導致全表掃描升級為表鎖。針對這三個維度,提供三套可立即生效的優化手段。
語法:在 SELECT 尾部加 WITH UR(Uncommitted Read,俗稱「髒讀」)。
SELECT col1, col2
FROM large_table
WHERE filter_col = 'VALUE'
WITH UR;
效果:
適用場景:報表查詢、統計分析、資料匯出、近似計算等可容忍讀到未提交資料的業務。
禁忌:財務核算、庫存扣減、帳戶餘額等強一致性場景絕對禁止。
在實例層級(db2set)啟用下列註冊表/環境變數,需 重啟實例生效:
| 參數 | 設定值 | 核心機制 | 適用場景 |
|---|---|---|---|
DB2_EVALUNCOMMITTED | ON | 謂詞評估 先於加鎖:先檢查行是否滿足 WHERE 條件,不滿足則直接跳過、不加鎖;滿足才加鎖。大幅縮減鎖持有時間與鎖數量。 | 高並發 OLTP,WHERE 選擇度高的查詢 |
DB2_SKIPINSERTED | ON | SELECT/UPDATE 自動跳過尚未提交的 INSERT 行(視同不可見),不等待提交、不報錯。 | 大量並發插入的隊列表、日誌表 |
DB2_SKIPDELETED | ON | SELECT/UPDATE 自動跳過尚未提交的 DELETE 行(視同已刪除),不等待提交完成。 | 高頻刪除/歸檔的業務表 |
啟用命令:
db2set DB2_EVALUNCOMMITTED=ON
db2set DB2_SKIPINSERTED=ON
db2set DB2_SKIPDELETED=ON
db2stop force; db2start # 必須重啟實例
風險提示:三參數均屬語義放寬,可能導致應用讀到「邏輯上不存在」或「還未確定」的資料,上線前務必在測試環境驗證業務正確性。
原理:無索引時,UPDATE/DELETE 需全表掃描,DB2 為保護一致性會在掃描過程對每一行加 X 鎖,甚至觸發鎖升級為表鎖,導致並發度歸零。
對策:
RUNSTATS),讓優化器選擇索引存取而非表掃描。效果:索引範圍掃描僅鎖定符合條件的極少量行,鎖佔用量級下降,並發度線性提升。
並發問題
├─ 讀多寫少、可容忍髒讀 → 方法一:WITH UR(最速效、零改造)
├─ 寫多讀多、需兼顧一致性 → 方法二:DB2_EVALUNCOMMITTED + SKIPINSERTED/DELETED(實例級、需重啟驗證)
└─ 特定高頻 SQL 耗時長、鎖等待高 → 方法三:補索引 + RUNSTATS(針對性最強、副作用最小)
WITH UR;核心交易層啟用 DB2_EVALUNCOMMITTED;熱點表補齊索引。db2pd -locks 觀察鎖數量/等待時間;MON_GET_APPL_LOCKWAIT 追蹤應用等待分佈。db2set -r 移除並重啟,索引可 DROP,風險可控。將這三把鑰匙納入 DB2 運維標準作業程序,能在不改動應用程式碼、不升級硬體的前提下,為系統釋放 2-10 倍的並發吞吐空間。