在oracle 10g中更新查询需要很长时间

时间:2014-07-22 08:42:46

标签: oracle oracle10g

我有一个表,其中包含超过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

1 个答案:

答案 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;