drop分区后索引不可用了,怎么办,

After drop the partition,the index became unusable,what should I do,

因为我把目标table分区为按月间隔分区,只保留27个月的数据(所以需要每月删除最旧的分区)。 我用下面SQL掉后,我运行SP,SP很慢

alter table target_table drop partition target_eldest_partition;

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

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

所以我用谷歌搜索了一下,得到了一些问题,请帮忙。

问题一:ANALYZE TABLE 不会重建索引,对吧?

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

问题 3:背景,实际上我的目标 table 的索引现在无法使用 SQL.

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

我在创建分区 table 时创建了我的索引 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" ;

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

问题4:如何解决索引不可用的问题,我分区后​​需要成熟的解决方案。

问题5:My目标table有5000万条数据,每个月大概190万条,所以我觉得用DBMS_STATS.GATHER_TABLE_STATS或者ANALYZE TABLE target_table COMPUTE STATISTICS更新统计是必要的,但是太慢了,还有什么办法吗

请大家帮忙指教。谢谢。

  • ANALYZE TABLE不会重建索引吧?

    我不知道,但现在你应该使用 DBMS_STATS.GATHER_TABLE_STATS 而不是 ANALYZE TABLE

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

  • 如果你的索引变成UNUSABLE那么它一定是一个全局索引。

  • 使用 UPDATE GLOBAL INDEXES 子句,即 alter table target_table drop partition target_eldest_partition UPDATE GLOBAL INDEXES; 或创建本地索引。

  • 取决于您索引了哪些列。除了整个 table,您还可以 运行 DBMS_STATS.GATHER_INDEX_STATS。使用 DBMS_STATS.GATHER_TABLE_STATS,您还可以仅指定单个分区甚至单个列。

顺便说一句,对于很多问题我的答案实际上应该是:"Did you consult the Oracle documentation"?或 "Do you know google"?根据您的屏幕截图,您对用户对象使用架构 SYS 和 table 空间 SYSAUX。你不应该那样做。创建您自己的用户并在此架构中创建任何对象。

分区索引一般分为三种:

  1. GLOBAL INDEX:您有一个跨越整个 table 的大索引。如果索引列不是分区键的一部分,那么这对于 UNIQUE INDEXES 来说是强制性的。实际上这样的索引没有分区。 (如图ALL_INDEXES
  2. LOCAL INDEX:该索引的分区方式与基础 table 相同。每个 table 分区都有相应的索引分区。
  3. PARTITIONED INDEX:此索引已分区,但与基础 table 不同。我认为甚至可以在非分区 table 上创建分区索引。分区索引仅限于非常特殊的用例。实际上我无法想象这样的索引在哪里有意义。

回答您的问题:

  1. ANALYZE TABLE 不会重建索引吧?

你不应该使用 ANALYZE TABLE - 使用 DBMS_STATS.GATHER_TABLE_STATISTICS。不,收集统计信息不会重建索引。

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

在这种情况下,"direct load" 问题不是问题所在。问题是您删除了一个分区,并且 table.

上有非本地索引
  1. 我的索引定义属于什么?

您显示的索引是非本地索引。因此,无论何时删除一个分区,它都会变得无效,因为删除的分区中的任何行都不再存在。解决方案是删除并重新创建索引作为 LOCAL 索引。它们的构建也简单得多。例如:

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

完成。

  1. 如何解决索引不可用的问题,删除分区后需要成熟的解决方案

使用本地索引。

  1. 我的目标 table 有 5000 万条数据,每个月大约 1,900,000 条,所以我认为使用 DBMS_STATS.GATHER_TABLE_STATS 或 ANALYZE TABLE target_table COMPUTE STATISTICS 来更新需要统计,但是太慢了,有没有其他的解决办法

使用 GATHER_TABLE_STATSESTIMATE_PERCENT 参数告诉它只对特定百分比的行进行采样。例如

DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=> 'NAME_OF_OWNER',
                              TABNAME => 'PER_LIMRA',
                              ESTIMATE_PERCENT => 5);

您还可以使用 DEGREE 参数告诉系统并行收集统计信息。您可以尝试不同的值,看看它是否对您的情况有帮助。

祝你好运。