DB2 巨大的 IREF 和大量掃描
我從一位同事那裡收到了一項任務,要檢查他為什麼總是收到高 CPU 負載警報。我對數據庫沒有太多經驗,我需要一些說明。我創建了一個腳本來擷取觸發警報時使用大部分 CPU 的前 5 個執行緒。順序幾乎總是相同的,前三個是 db2agents,另外兩個是 db2pfchr。據我所知,我發現 SQL 語句沒有任何問題,因此我檢查了表掃描和 IREF。
我立即註意到的是讀取的行和選擇的行之間的區別,例如:
Rows deleted = 0 Rows inserted = 0 Rows updated = 1329 Rows selected = 714 Rows read = 3903430587518 Rows written = 3471
前 3 個最大的表掃描值為 26586532、15538513 和 942177。第一個表有一個從未使用過的索引,第二個表有一個使用了大約 70k 次的索引,第三個表沒有索引。
所以,我的明顯猜測是需要添加索引以避免表掃描
因為我從來沒有在我的生活中添加過索引並且必須閱讀更多關於它的資訊,所以我需要確定我的假設,也許還有其他需要檢查的東西?此外,查詢中的所有值都是“?”……隱藏?像 UPDATE X SET VALUE_INT = ?, VALUE_STRING = ?, Y = CURRENT TIMESTAMP WHERE AB = ?
這是一個 OLTP DB,它是關於 RHEL IREF 上的 DB2 V10.5 - 索引讀取效率 = ROWS READ/ROWS RETURNED
您可以找出導致最多讀取行的語句:
select num_executions, rows_read, stmt_text from sysibmadm.snapdyn_sql order by 2 desc fetch first 5 rows only
如果
UPDATE X SET VALUE_INT = ?, VALUE_STRING = ?, Y = CURRENT TIMESTAMP WHERE AB = ?
是罪魁禍首,您可能需要在 X.AB 上添加索引:CREATE INDEX ... ON X (AB) ALLOW REVERSE SCANS COLLECT SAMPLED DETAILED STATISTICS
索引有無數種可能的選項,但像上面這樣的東西通常就足夠了。如果您有權訪問 db2exfmt,您可以比較之前和之後的計劃,例如:
db2 "set explain mode explain" db2 "UPDATE X SET VALUE_INT = ?, VALUE_STRING = ?, Y = CURRENT TIMESTAMP WHERE AB = ?" db2exfmt -d <db> -g -1 -o before.exfmt db2 "set explain mode no" db2 "create index ..." db2 "set explain mode explain" db2 "UPDATE X SET VALUE_INT = ?, VALUE_STRING = ?, Y = CURRENT TIMESTAMP WHERE AB = ?" db2exfmt -d <db> -g -1 -o after.exfmt db2 "set explain mode no"
全部憑記憶,所以里面可能有一兩個小故障