删除分区后,索引变得不可用,该怎么办,

时间:2018-07-16 03:38:02

标签: oracle indexing partitioning

当我按月对目标表进行分区时,仅保留27个月的数据(因此需要每月删除最旧的分区)。 在使用下面的SQL删除它之后,我运行了SP,该SP非常慢。

alter table target_table drop partition target_eldest_partition;

所以我取消了SP并分析了表

ANALYZE TABLE target_table  COMPUTE STATISTICS;     

但遇到错误

Error starting at line : 12 in command -
ANALYZE TABLE per_limra COMPUTE STATISTICS
Error report -
ORA-01502: index 'target_index' or partition of such index is in unusable state
01502. 00000 -  "index '%s.%s' or partition of such index is in unusable state"
*Cause:    An attempt has been made to access an index or index partition
           that has been marked unusable by a direct load or by a DDL
           operation
*Action:   DROP the specified index, or REBUILD the specified index, or
           REBUILD the unusable index partition

所以我用Google搜索它并遇到了一些问题,请帮忙。

问题1:ANALYZE TABLE无法重建索引,对吗?

问题2:索引错误原因,*Cause: ........ by a direct load是什么意思?

问题3:背景,实际上,通过使用以下SQL进行检查,现在无法使用我的目标表的索引。

SELECT owner, index_name, tablespace_name
FROM   dba_indexes
WHERE  status = 'UNUSABLE';

使用下面的SQL创建分区表时,我会创建索引

  CREATE INDEX "schema_name"."target_index1" ON "schema_name"."target_table" ("col1") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS NOLOGGING 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "target_tablespace" ;

我知道使用分区表时,索引有两种类型,全局索引和本地索引,我的索引定义属于什么?似乎我没有使用分区索引,因为在这里找不到目标表分区名称。enter image description here

enter image description here 问题4:如何解决无法使用的索引问题,删除分区后需要成熟的解决方案。

问题5:我的目标表有5000万个数据,每个月约有190万个数据,所以我认为有必要使用DBMS_STATS.GATHER_TABLE_STATSANALYZE TABLE target_table COMPUTE STATISTICS更新统计信息,但这太慢了,任何其他解决方案。

请帮助提供建议。谢谢。

2 个答案:

答案 0 :(得分:2)

  • ANALYZE TABLE无法重建索引,对吧?

    我不知道,但是现在您应该使用${randomSource}而不是${randomDestination}

  • 直接加载意味着数据不是逐行插入,而是成批插入,请参见Direct Path Load

  • 如果您的索引变为DBMS_STATS.GATHER_TABLE_STATS,则它必须是全局索引。

  • 使用ANALYZE TABLE子句,即UNUSABLE或创建本地索引。

  • 取决于已建立索引的列。除了整个表,您还可以运行UPDATE GLOBAL INDEXES。使用alter table target_table drop partition target_eldest_partition UPDATE GLOBAL INDEXES;,您还可以仅指定单个分区,甚至指定单个列。

顺便说一句,对于许多问题,我的答案实际上应该是:“您参考了Oracle文档”吗?或“您知道谷歌”吗?根据您的屏幕截图,您将模式DBMS_STATS.GATHER_INDEX_STATS和表空间DBMS_STATS.GATHER_TABLE_STATS用于用户对象。你不应该那样做。创建您自己的用户并在此架构中创建任何对象。

通常有三种类型的分区索引:

  1. GLOBAL INDEX:您有一个跨整个表的大索引。例如,如果索引列不属于分区键,则这对于UNIQUE INDEXES是必需的。实际上,这种索引没有分区。 (如SYS中所示)
  2. LOCAL INDEX:此索引的分区方式与基础表相同。每个表分区都有一个相应的索引分区。
  3. PARTITIONED INDEX:此索引已分区,但与基础表相比不同。我认为甚至有可能在非分区表上创建分区索引。分区索引仅限于非常特殊的用例。实际上,我无法想象这样的索引在哪里有意义。

答案 1 :(得分:1)

要掩盖您的问题:

  1. ANALYZE TABLE不重建索引,对吧?

永远不要使用ANALYZE TABLE-使用DBMS_STATS.GATHER_TABLE_STATISTICS。而且,收集统计信息不会重建索引。

  1. 索引错误原因,*原因:........直接加载是什么意思?

在这种情况下,“直接加载”问题不是问题。问题是您删除了一个分区,并且表上有非本地索引。

  1. 我的索引定义属于什么?

您显示的索引是非本地索引。因此,每当您删除分区时,该分区将变得无效,因为删除的分区中的任何行都不再存在。解决方案是删除索引并将其重新创建为LOCAL索引。它们也更容易构建。例如:

CREATE INDEX "schema_name"."target_index1"
  ON "schema_name"."target_table" ("col1")
  LOCAL;

完成。

  1. 该如何解决无法使用的索引问题,删除分区后我需要一个成熟的解决方案。

使用本地索引。

  1. 我的目标表有5000万个数据,每个月约有190万个数据,所以我认为使用DBMS_STATS.GATHER_TABLE_STATS或ANALYZE TABLE target_table COMPUTE STATISTICS来更新统计信息是必要的,但这太慢了,有其他解决方案。 / li>

使用ESTIMATE_PERCENT的{​​{1}}参数来告诉它仅对一定百分比的行进行采样。例如

GATHER_TABLE_STATS

您还可以使用DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=> 'NAME_OF_OWNER', TABNAME => 'PER_LIMRA', ESTIMATE_PERCENT => 5); 参数来告诉系统并行收集统计信息。您可以尝试使用其他值来查看它是否对您有帮助。

好运。

相关问题