Oracle:如何进行索引范围扫描,跳过子键的范围?

时间:2016-01-30 05:46:35

标签: oracle indexing oracle12c

我使用的是Oracle 12c。

考虑一个表名称GRID_CELLS,它存储100,000 x 100,000网格单元数据。列如下:

  • X号
  • Y号
  • CELL_VALUE数字

索引由(X,Y)组成,它是主键。

由于它是网格单元格数据,几乎所有的单元格都是如此。有记录。

如果查询是这样的:

select * from GRID_CELLS where X >= 100 and X <= 200 and Y >= 100 and Y <= 200

Oracle将选择索引范围扫描,并将按如下方式执行:

  1. 从根节点遍历B树索引以查找第一个叶节点
  2. 通过rowid
  3. 访问表行的最后一个叶节点,一直扫描叶节点

    也就是说,Oracle读取叶子节点大约100,000 * 100条记录,这比下面的(假设的)动作慢很多。

    1. 从根遍历B树索引以查找(&gt; = 100,&gt; = 100)的第一个叶节点
    2. 扫描叶节点,直到找到Y值大于200
    3. 的记录
    4. 停止叶子节点扫描并从根节点重新遍历B树索引以进行下一个X
    5. 重复2和3
    6. Oracle可以这样做吗?如果是这样,怎么可能被迫这样做呢?还是有其他最佳解决方案吗?

      BTW,我们不能使用分区。因此,分区不是解决方案。

      更新

      我根据下面的评论测试了2位图索引配置。结果是积极的。它比B树索引范围扫描快5~10倍。

      但是,如果Oracle在范围扫描B树索引时跳过叶节点,那么它仍然会很好。

1 个答案:

答案 0 :(得分:0)

位图索引是一种可行的方法。当使用位图索引时,甚至星形变换也是最佳的。位图索引的问题在于,当X和Y有许多不同的值时,它们很大且查询速度较慢。当表中存在的不同X和Y值的总数小于行数时,它们是最佳的。 / p>

还有一些其他步骤可以加快查询速度:

您可以按X或Y或两者对表进行分区。在这种情况下,速度增益取决于X和Y值的分布以及您的查询是否选择了一系列值。

您可以在X和Y上创建功能索引,或者将X和Y连接成一个字符串,然后在该字符串上创建索引。那你就只有一把钥匙。这可能是最好的解决方案,因为它可以将执行复杂度降低一度。

如果执行期间的磁盘I / O很高,那么将此表转换为IOT(索引组织表)将为您带来好处,但对于包含许多列的表通常就是这种情况。

在决定索引策略时,您必须始终牢记此表在生产环境中的读/写比率。如果存在高读取计数(SELECT)和低写入计数(INSERT),则需要将大部分处理写入部分:对表进行分区,创建功能索引等。如果存在高写入次数和低读取次数以及SELECT速度并不是那么重要,那么X和Y上的一个索引是最好的解决方案。