招式一:降低隔離層級 (Statement/Session 級)
SELECT ... WITH UR -- Uncommitted Read,無鎖讀取
- 適用:報表、日誌查詢、可容忍髒讀場景。
- 效果:完全消除讀取鎖,並發度最高。
招式二:Registry 變數改變鎖檢查時機
db2set DB2_EVALUNCOMMITTED=ON -- 謂詞評估前置,減少鎖持有時間
db2set DB2_SKIPINSERTED=ON -- 跳過未提交 INSERT 列
db2set DB2_SKIPDELETED=ON -- 跳過未提交 DELETE 列
- 需 `db2stop && db2start` 生效(實例級)。
- `EVALUNCOMMITTED`:先評估 WHERE 條件,**不滿足則不加鎖**,大幅降低鎖衝突。
- `SKIPINSERTED`:`SELECT`/`UPDATE` 直接忽略未提交的新列,不等待。
- `SKIPDELETED`:視未提交刪除列為已刪除,不等待鎖釋放。
- **注意**:可能讀到不一致狀態(如 `SKIPDELETED` 導致 `COUNT(*)` 偏低),需業務評估可接受度。
招式三:WHERE 條件欄位建立索引
- 無索引 → 掃描全表 → 對大量列加鎖(甚至升級為表鎖)。
- 有索引 → 索引範圍掃描 → 僅鎖定符合條件的少量列/鍵值。
- 效果:從根源縮小鎖粒度與數量,同時提升查詢速度。
綜合建議
| 場景 | 推薦組合 |
| 高併發 OLTP 核心交易 | CS 隔離 + 關鍵索引 + `EVALUNCOMMITTED=ON` |
| 大量報表/BI 查詢 | `WITH UR` + 物化查詢表 (MQT) |
| 批次更新/清理 | `SKIPDELETED=ON` + 分批 Commit + 適當索引 |
| 長時間唯讀游標 | `WITH CS` + `WITH HOLD` + 索引覆蓋 |