三張百萬級分區表(以 ACCTSTRINGDATE 為分區鍵)進行 INNER JOIN,原 SQL 執行 60+ 秒,目標 <5 秒。
SELECT /*+ PARALLEL(src, 8) */ DISTINCT
src.systemname, src.databasename, src.tablename, src.username
FROM meta_dbql_table_usage_exp_hst src
INNER JOIN dr_qry_log_exp_hst rl
ON src.acctstringdate = rl.acctstringdate
AND src.queryid = rl.queryid
AND src.systemname = rl.systemname
INNER JOIN meta_dr_qry_log_tgt_all_hst tgt
ON UPPER(tgt.systemname) = UPPER('MOZART')
AND UPPER(tgt.databasename) = UPPER('GDW_TABLES')
AND UPPER(tgt.tablename) = UPPER('SSA_SLNG_LSTG_MTRC_SD')
AND src.acctstringdate = tgt.acctstringdate
AND rl.statement_id = tgt.statement_id
AND rl.systemname = tgt.systemname
AND tgt.acctstringdate > SYSDATE - 30
AND NOT ( ...排除條件... )
AND tgt.systemname IS NOT NULL ...
計畫顯示兩層 NESTED LOOPS,最內層對 META_DBQL_TABLE_USAGE_EXP_HST 執行 全表掃描(Id 15),導致大量重複 I/O。
驅動資料集小,且被驅動表在連接欄位上有索引。
-- 現有索引
META_DR_QRY_LOG_TGT_ALL_IDX ON (STATEMENT_ID, ACCTSTRINGDATE)
META_DBQL_TUSAGE_EHST_IDX ON (QUERYID, ACCTSTRINGDATE)
DR_QRY_LOG_EXP_HST_IDX ON (QUERYID, ACCTSTRINGDATE)
-- 缺少:DR_QRY_LOG_EXP_HST 在 STATEMENT_ID 上的索引
-- 因與 TGT 表以 STATEMENT_ID + ACCTSTRINGDATE 聯結
CREATE INDEX dr_qry_log_exp_hst_idx2
ON gv.dr_qry_log_exp_hst (statement_id, acctstringdate) LOCAL;
INDEX RANGE SCAN (DR_QRY_LOG_EXP_HST_IDX2)(Id 9)。TABLE ACCESS BY LOCAL INDEX ROWID 取代全表掃描。| 指標 | 優化前 | 優化後 |
|---|---|---|
| 執行時間 | 60+ 秒 | 2 秒 |
| 內層存取方式 | Full Table Scan | Index Range Scan |