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
。你不应该那样做。创建您自己的用户并在此架构中创建任何对象。
分区索引一般分为三种:
- GLOBAL INDEX:您有一个跨越整个 table 的大索引。如果索引列不是分区键的一部分,那么这对于 UNIQUE INDEXES 来说是强制性的。实际上这样的索引没有分区。 (如图
ALL_INDEXES
)
- LOCAL INDEX:该索引的分区方式与基础 table 相同。每个 table 分区都有相应的索引分区。
- PARTITIONED INDEX:此索引已分区,但与基础 table 不同。我认为甚至可以在非分区 table 上创建分区索引。分区索引仅限于非常特殊的用例。实际上我无法想象这样的索引在哪里有意义。
回答您的问题:
- ANALYZE TABLE 不会重建索引吧?
你不应该使用 ANALYZE TABLE - 使用 DBMS_STATS.GATHER_TABLE_STATISTICS。不,收集统计信息不会重建索引。
- 索引错误原因,*Cause: ....... by a direct load 是什么意思?
在这种情况下,"direct load" 问题不是问题所在。问题是您删除了一个分区,并且 table.
上有非本地索引
- 我的索引定义属于什么?
您显示的索引是非本地索引。因此,无论何时删除一个分区,它都会变得无效,因为删除的分区中的任何行都不再存在。解决方案是删除并重新创建索引作为 LOCAL 索引。它们的构建也简单得多。例如:
CREATE INDEX "schema_name"."target_index1"
ON "schema_name"."target_table" ("col1")
LOCAL;
完成。
- 如何解决索引不可用的问题,删除分区后需要成熟的解决方案
使用本地索引。
- 我的目标 table 有 5000 万条数据,每个月大约 1,900,000 条,所以我认为使用 DBMS_STATS.GATHER_TABLE_STATS 或 ANALYZE TABLE target_table COMPUTE STATISTICS 来更新需要统计,但是太慢了,有没有其他的解决办法
使用 GATHER_TABLE_STATS
的 ESTIMATE_PERCENT
参数告诉它只对特定百分比的行进行采样。例如
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=> 'NAME_OF_OWNER',
TABNAME => 'PER_LIMRA',
ESTIMATE_PERCENT => 5);
您还可以使用 DEGREE
参数告诉系统并行收集统计信息。您可以尝试不同的值,看看它是否对您的情况有帮助。
祝你好运。
因为我把目标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 分区名称。
问题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
。你不应该那样做。创建您自己的用户并在此架构中创建任何对象。
分区索引一般分为三种:
- GLOBAL INDEX:您有一个跨越整个 table 的大索引。如果索引列不是分区键的一部分,那么这对于 UNIQUE INDEXES 来说是强制性的。实际上这样的索引没有分区。 (如图
ALL_INDEXES
) - LOCAL INDEX:该索引的分区方式与基础 table 相同。每个 table 分区都有相应的索引分区。
- PARTITIONED INDEX:此索引已分区,但与基础 table 不同。我认为甚至可以在非分区 table 上创建分区索引。分区索引仅限于非常特殊的用例。实际上我无法想象这样的索引在哪里有意义。
回答您的问题:
- ANALYZE TABLE 不会重建索引吧?
你不应该使用 ANALYZE TABLE - 使用 DBMS_STATS.GATHER_TABLE_STATISTICS。不,收集统计信息不会重建索引。
- 索引错误原因,*Cause: ....... by a direct load 是什么意思?
在这种情况下,"direct load" 问题不是问题所在。问题是您删除了一个分区,并且 table.
上有非本地索引- 我的索引定义属于什么?
您显示的索引是非本地索引。因此,无论何时删除一个分区,它都会变得无效,因为删除的分区中的任何行都不再存在。解决方案是删除并重新创建索引作为 LOCAL 索引。它们的构建也简单得多。例如:
CREATE INDEX "schema_name"."target_index1"
ON "schema_name"."target_table" ("col1")
LOCAL;
完成。
- 如何解决索引不可用的问题,删除分区后需要成熟的解决方案
使用本地索引。
- 我的目标 table 有 5000 万条数据,每个月大约 1,900,000 条,所以我认为使用 DBMS_STATS.GATHER_TABLE_STATS 或 ANALYZE TABLE target_table COMPUTE STATISTICS 来更新需要统计,但是太慢了,有没有其他的解决办法
使用 GATHER_TABLE_STATS
的 ESTIMATE_PERCENT
参数告诉它只对特定百分比的行进行采样。例如
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=> 'NAME_OF_OWNER',
TABNAME => 'PER_LIMRA',
ESTIMATE_PERCENT => 5);
您还可以使用 DEGREE
参数告诉系统并行收集统计信息。您可以尝试不同的值,看看它是否对您的情况有帮助。
祝你好运。