我有一个表,其中包含超过200万条记录,我正在尝试使用以下查询更新表
UPDATE toc T
SET RANK =
65535
- (SELECT COUNT (*)
FROM toc T2
WHERE S_KEY LIKE '00010001%'
AND A_ID IS NOT NULL
AND T2.TARGET = T.TARGET
AND T2.RANK > T.RANK)
WHERE S_KEY LIKE '00010001%' AND A_ID IS NOT NULL
通常这个查询花了5分钟来更新我们的暂存数据库中的50000行,这是生产数据库的精确副本,但是在我们的生产数据库中需要6个小时来执行...
我尝试了Oracle顾问来选择正确的执行计划,但没有任何工作......
计划
UPDATE STATEMENT ALL_ROWSCost: 329,471
6 UPDATE TT.TOC
2 TABLE ACCESS BY INDEX ROWID TABLE TT.TOC Cost: 5 Bytes: 4,173,236 Cardinality: 54,911
1 INDEX SKIP SCAN INDEX TT.DATASTAT_SORTKEY_IDX Cost: 4 Cardinality: 1
5 SORT AGGREGATE Bytes: 76 Cardinality: 1
4 TABLE ACCESS BY INDEX ROWID TABLE TT.TOC Cost: 5 Bytes: 76 Cardinality: 1
3 INDEX SKIP SCAN INDEX TT.DATASTAT_SORTKEY_IDX Cost: 4 Cardinality: 1
我可以看到以下等待事件
1,066 db file sequential read 10,267 0 3,993 0 6 39,933,580
1,066 db file scattered read 413 0 188 0 6 1,876,464
非常感谢任何帮助。
这是当前的索引列表
DSTAT_SKEY_IDX D_STATUS 1
DSTAT_SKEY_IDX S_KEY 2
IDX$$_165A0002 N_LABEL 1
S_KEY_IDX S_KEY 1
XAK1_TOC N_RELATIONSHIP 1
XAK2_TOC TARGET 1
XAK2_TOC N_LABEL 2
XAK2_TOC D_STATUS 3
XAK2_TOC A_ID 4
XIE1_TOC N_RELBASE 1
XIF4_TOC SOURCE_FILE_ID 1
XIF5_TOC A_ID 1
XPK_TOC N_ID 1
与Atif
答案 0 :(得分:1)
您正在进行跳过扫描,您可能希望进行范围扫描。
只有当索引列按降序选择性排序时才能进行范围扫描 - 在您的情况下,它似乎应该是S_KEY - TARGET - RANK
更新:以不同的顺序重写查询不会有任何区别。重要的是该表的索引中列的顺序。
首先向我们展示该表的当前索引列:
select index_name, column_name, column_position from all_ind_columns where table_name = 'TOC'
然后你可以创建一个新的索引,例如
create index toc_i_s_key_target_rank on toc (s_key, target, rank) compress;