【问题标题】:Confused about Composite Indexes and FFS对复合索引和 FFS 感到困惑
【发布时间】:2015-12-08 20:15:24
【问题描述】:

我已经阅读了很多关于 Oracle 索引和各种类型的索引扫描的文章,尤其是快速全扫描 (ffs)。我的问题将是关于不同索引定义的 ffs 的性能。我将描述我认为我对索引构建和快速全扫描的了解,因为很可能,我的理解存在漏洞或错误。

Oracle 的索引通常由 B 树支持,其中分支是指向已排序键范围的指针。生成的键取决于索引指定的列。

如果我在列 (A, B) 上有一个索引,那么按照排序顺序,一些叶节点可能看起来像这样。关键是首先对 A 列进行排序,然后对 B 列进行排序。每个键都指向表中的某个行 ID。

A1-B1 -> rowid 5
A1-B1 -> rowid 7
A1-B2 -> rowid 12
A1-B3 -> rowid 24
A2-B3 -> rowid 123
A2-B3 -> rowid 2412
A2-B3 -> rowid 241
A3-B1 -> rowid 234
A3-B2 -> rowid 213

假设我们有 2 个分支,这些分支可能包含以下数据

Branch 1:
Range: A1-B1 to A2-B3
Children Leaf nodes with row ids: [5, 7, 12, 24, 123]

Branch 2:
Range: A2-B3 to A3-B2
Children Leaf nodes with row ids: [2412, 241, 234, 213]

查找应该只是简单的二分查找。

关于快速全扫描:我理解如果一个查询只选择索引包含的列,那么我们不需要看表。索引充当微型/瘦表,即我们可以直接查询索引而无需查找表。只要查询没有 ORDER BY 子句,我们就可以使用快速全扫描来扫描索引。我相信快速全扫描只是通过我们拥有的任何选择器子句来查找多个块和过滤器。

最后是我的问题:

考虑两个索引 X 和 Y:

X is an index on columns (A, B)
Y is an index on columns (A, B, C)

我假设以下 SQL 应该使用 ffs 执行 X 和 Y 索引。

select count(1) from table where A in (a1, a2) and B <= b';

两个索引在 ffs 期间是否存在性能差异? 索引 Y 执行“较慢”是因为 SQL 仅在 A 和 B 上具有谓词吗?

我也想知道“多块读取”是什么意思。什么是块?是叶子节点的一部分吗?使用上面的例子,分支 1 的所有叶子节点都是一个块,分支 2 的所有叶子节点都是另一个块吗?这是多线程、分而治之的阅读方式吗?即每个线程读取自己的块并聚合结果?

谢谢!

【问题讨论】:

标签: sql oracle performance indexing


【解决方案1】:

索引树看起来像你只在索引唯一时写的。

在大多数情况下,优化器选择索引 X,仅仅是因为它的大小会更小 - 仅包含两列。如果索引很大并且扫描的数据量差异也很大,您会注意到差异。

块是Oracle数据库中最小的数据单元。默认大小为 8 kb(范围 2 kB - 32 kB),Oracle 中的每个数据对象(如索引)都由段 -> 范围 -> 块组成。所以索引的所有根、分支和叶子都存储在块中。如果条目数很少,则根块是叶块并且没有分支。所以你的描述在更大的范围内是正确的。

如果扫描是并行的,则范围是块的连续范围,因此定义子范围不是问题,因此进程不会共享相同的数据。

多块读取是典型的,当不需要读取排序数据时,您可以以与一个相同的努力读取许多块(接近所需),例如您只需计算的示例查询。

【讨论】:

  • 糟糕,抱歉,我不清楚。我们没有同时创建 X 和 Y 索引。所以我想知道使用 X 与使用 Y 的性能如何。块和多块读取是有意义的。谢谢!
  • 在您描述的仅完整扫描索引的单一情况下,差异应该不大。索引是非常广泛的领域,就像大多数事情一样,它取决于您想要实现的目标。通常有利有弊。这取决于很多事情,如果您打算更多地使用索引进行查找,或者正如您提到的瘦表版本,表修改了多少。索引中列的顺序也很重要。
  • 嗯,这是我的另一个问题。有人告诉我,如果我们最初有索引 X,SQL 会运行得很快。但是如果我们将 X 更新为 Y(将 C 添加到索引中),SQL 的执行速度就会变慢。我不明白为什么这是真的,为什么 SQL 会执行得更慢。
  • 取决于 SQL 和许多其他的东西。例如,如果 A 列和 B 列中的许多值都可以为空,并且您将 C 列添加到索引中,则索引将更大,因为它将包含更多行。如果 C 列中的值经常更新,则将涉及索引维护。还取决于列 C 的大小,如果 A 和 B 是几个字节,而 C 是数百个,则索引也会大得多。
  • 为什么会有更多行?我假设更多的行意味着更多的叶节点和可能更多的分支?我认为叶节点是表中一行的 1 对 1 映射。所以我认为索引 X 和 Y 的叶节点数应该相同
猜你喜欢
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
相关资源
最近更新 更多