Oracle 9i 引入「唯讀模式獲取 CBC Latch」優化:純查詢(全表掃描/索引範圍掃描)以共享模式獲取 Cache Buffers Chains (CBC) Latch,降低獨佔模式爭用。但實測發現高併發下仍有顯著爭用。
-- 1. 建表
CREATE TABLE test (a INT, b VARCHAR2(20));
-- 2. 載入 50,000 筆資料
BEGIN
FOR i IN 1..50000 LOOP
INSERT INTO test VALUES (i, 'adsfsafsa');
END LOOP;
COMMIT;
END;
/
-- 3. 建立索引
CREATE INDEX test_i ON test(a);
-- 4. 存儲過程:大量索引掃描
CREATE OR REPLACE PROCEDURE test_k IS
BEGIN
FOR rec IN (SELECT /*+ INDEX(TEST TEST_I) */ * FROM test WHERE a > 20000) LOOP
NULL;
END LOOP;
END;
/
-- 開啟 2000 個 DBMS_JOB 並行執行 test_k
VAR i NUMBER;
BEGIN
FOR j IN 1..2000 LOOP
DBMS_JOB.SUBMIT(:i, 'TEST_K;');
COMMIT;
END LOOP;
END;
/
Cpu(s): 16.3%us, 83.7%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
唯讀模式獲取 CBC Latch 並未徹底解決熱塊爭用問題,僅降低爭用嚴重度。
原因分析:
| 策略 | 原理 | 適用性 |
|---|---|---|
| 增加 `_db_block_hash_buckets` (隱含參數) | 擴大雜湊桶數,分散熱塊到不同 Latch | 需 Oracle 支援建議,風險較高 |
| 調整索引結構:Reverse Key Index / Partitioned Index | 分散插入/掃描熱點 | 適用特定存取模式 |
| 應用層面:快取熱門查詢結果、減少重複掃描 | 降低根源併發度 | 最穩健、效果最好 |
| 升級至 11gR2+ | 引入 CBC Latch 子分區、無鎖一致性讀 | 根治方案 |
唯讀模式 CBC Latch 是重要優化里程碑,但非銀彈。面對極高併發索引掃描場景,**架構層面分散熱點**與**應用層面減少重複存取**才是根本出路。測試方法(建表→建索引→存儲過程→DBMS_JOB 施壓→觀察 `latch: cache buffers chains` 與 CPU `sy%`)可作為評估新版本/參數效果的標準基準。