【发布时间】:2011-05-09 15:56:42
【问题描述】:
我很确定这不能在 Oracle 中完成,但我很想被证明是错误的......
假设我有一个包含很多列的大表,我想在十几个列上创建索引。使用 Oracle,我会触发几个连续的 create index 语句,然后开始烧水壶。
每个create index都需要扫描表中的每一行来形成索引。
即10 个索引 = 10 次完整扫描。
您会认为一个明显的优化是扫描表一次并同时索引 10 列。你不会吗?
create indexes on mytable (
ix_mytable_cola (cola),
ix_mytable_colb (colb),
ix_mytable_colc (colc)
);
很明显,它不存在一定有很好的理由。
有什么想法吗?
我可以在单独的会话中同时触发每个create index,并希望数据库缓冲区缓存能挽救这一天,但似乎是一个很长的机会。
编辑
我没有得到明确的答案,所以我在 Oracle-L 上问了同样的问题:
http://www.freelists.org/post/oracle-l/Creating-multiple-indexes
普遍的共识是它不可用,但可能是一个有用的功能。最有用的回复来自David Aldridge,他建议如果同时启动所有创建索引语句,那么 Oracle 将“做正确的事”。
【问题讨论】:
-
我从未使用过 Oracle,所以这可能无关紧要。无论如何,您不能创建一个具有相同结构和所需索引的新空表,然后从原始表中填充它吗?这可能会也可能不会满足您的要求,并且它当然会暂时使磁盘需求增加一倍。它仍然可以工作:)
-
如果我理解正确,您想动态创建索引,但是您不能事先创建索引的原因是什么?
-
感谢您的建议。但是,预先创建索引的想法不适用于数据仓库大小的表。将数据加载到具有预先存在的索引的表中是一个真正的性能杀手(即使 - 在 Oracle 的情况下 - 索引创建可能会延迟到数据加载完毕)。通常在数据仓库的情况下,您会将数据加载到具有尽可能少的索引的表中,然后再重建索引。
-
@Jürgen Hollfelder - 是的,当然可以并行创建索引,但创建每个索引需要对表进行全面扫描。我建议这可以优化为单个完整扫描,其中要索引的每一列在处理每一行时都被采样。如果数据库缓冲区缓存恰好保存了每个并行会话所需的相关块(即使这样仍然需要每个会话从缓冲区缓存中读取的开销),这只会在并行创建索引时发生。
-
... 想象一下,您如何编写代码创建 10 个列的内容的 10 个哈希映射 - 您是循环遍历表行 10 次,还是循环遍历一次并一次创建 10 个哈希映射?