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

Posted

技术标签:

【中文标题】在 oracle 10g 中更新查询需要很长时间【英文标题】:Update query taking long time in oracle 10g 【发布时间】:2014-07-22 08:42:46 【问题描述】:

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

阿提夫

【问题讨论】:

【参考方案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;

【讨论】:

不确定我应该怎么做...我应该以不同的顺序重写查询吗? 我刚刚在问题中添加了索引

以上是关于在 oracle 10g 中更新查询需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

想要从选择查询中处理 5000 条记录在 oracle 数据库中需要很长时间

结果集需要很长时间来处理来自 Oracle 的大数据

尽管成本低、基数低,但 Oracle 中的选择查询需要很长时间

Oracle Forms 10g,多次插入和更新不起作用

带有子查询的 Oracle 更新 - 性能问题

Oracle10g新特性——正则表达式 - 转