当将数据仓库批量数据加载到不需要日志记录的表中时,通常我的流程是:
- 截断表
- 删除索引
- 插入/*+附加*/
- 重新创建索引而不记录
这很好,但删除并重新创建索引可能会导致问题,所以我想知道大家是否认为这一步是必要的。据我所知,从 10g 开始,这种索引创建已经过优化,因此索引会在数据加载后重新构建。
有人有这样的经历吗?
答案1
您说删除并重新创建索引会产生问题。另一种方法是将索引标记为不可用,然后重建它们。这样,即使某些步骤失败,它们的定义(名称、列、表空间等)也不会“丢失”。
因此,在步骤 2 中循环遍历表的所有索引并运行:
更改索引 my_index_name 不可用;
在步骤 4 中循环索引并重建。您可以指定 nologging、所需的并行级别、索引压缩等:
更改索引 my_index_name 重建无日志并行 16;
一次性构建索引比“逐行”构建索引更有效。在第一种情况下,Oracle 会进行一次全表扫描、排序并写入索引。如果索引在批量加载期间维护,则它会在加载期间一直更新,因此它需要不断更新其叶块,从而执行更多工作和 I/O。为什么?因为每个索引块将在加载的不同时间点更新多次。
顺便说一句 - 希望你有一个“第 5 步” - 收集表和索引的统计信息(并行)
答案2
我们的做法几乎相同,只是我们将数据批量加载到临时暂存表,然后传输到实际表。我认为在数据加载后创建索引是一个非常正常的 ETL 步骤,不会造成任何问题。这需要一些时间,但如果没有索引,速度会慢得多。我们从未遇到过在已填写的表上创建索引的任何问题。