oracle 分割分区后未使用索引

huwehgph  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(109)

我们有一个表A,它有大约4亿条带索引的记录:

  • 列1上的idx 1
  • 列2上的idx 2
  • 列3上的idx 3

并在列4上进行分区,如下所示。
part1具有数据<='31-Dec-16',并且在此之后,每日分区可用。

然后在UAT中,我们决定将分区Part1拆分为日常分区,但在此之后,表A上的查询执行缓慢。

在UAT环境中采用全表扫描而不是索引扫描,但在尚未实现分割分区的prod**环境中,正在执行索引扫描。

wgx48brx

wgx48brx1#

当您分割、合并、删除或截断分区时,所有 global(非本地)索引立即无效(索引段实际上被删除,因为它包含无效的ROWID),然后必须重建:

ALTER INDEX idx1 REBUILD PARALLEL (DEGREE 16) NOLOGGING;
ALTER INDEX idx2 REBUILD PARALLEL (DEGREE 16) NOLOGGING;
ALTER INDEX idx3 REBUILD PARALLEL (DEGREE 16) NOLOGGING;

本地索引永远不会作为一个整体失效,但在分区拆分或合并期间,受影响的索引分区将无效,而其他分区仍然有效。如果是这样的话,除非你的查询修剪到一个特定的分区,在那里它需要的索引仍然有效,否则一个无效的索引分区将使整个事情无法被查询使用。使用以下命令标识无效索引分区:

SELECT index_name,partition_name
  FROM all_ind_partitions
 WHERE status = 'UNUSABLE'

重建:

ALTER INDEX idx1 REBUILD PARTITION Jan2023 PARALLEL (DEGREE 16) NOLOGGING;
ALTER INDEX idx1 REBUILD PARTITION Feb2023 PARALLEL (DEGREE 16) NOLOGGING;

等等.
如果你有很多分区要做,那么一个简单的PL/SQL循环和EXECUTE IMMEDIATE可以快速重建它们:

BEGIN
  FOR rec_part IN (SELECT index_name,partition_name
                     FROM all_ind_partitions
                    WHERE status = 'UNUSABLE'
                      AND index_name IN ('IDX1','IDX2','IDX3'))
  LOOP
    EXECUTE IMMEDIATE 'ALTER INDEX "'||rec_part.index_name||'" REBUILD PARTITION "'||rec_part.partition_name||'" PARALLEL (DEGREE 16) NOLOGGING';
  END LOOP;
END;

相关问题