我已经阅读了很多关于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)
我假设应该使用ffs为BOTH X和Y索引执行以下SQL。
select count(1) from table where A in (a1, a2) and B <= b';
两个索引的ffs期间是否存在性能差异? 索引Y是否执行得更慢&#34;因为SQL只有A和B的谓词?
我也想知道&#34;多块读取&#34;&#34;意思。什么是街区?它是叶节点的一部分吗?使用上面的例子,分支1的所有叶子节点都是一个块,所有分支2的叶子节点是另一个块吗?这是一个多线程,分而治之的阅读?即每个线程读取自己的块并聚合结果?
谢谢!
答案 0 :(得分:2)
索引树看起来就像你只在索引是唯一的时才写的。
在大多数情况下,优化器会选择索引X,因为它的大小会更小 - 只包含两列。如果索引很大并且扫描的数据量差异很大,您会注意到差异。
Block是Oracle数据库中最小的数据单元。默认大小为8 kb(范围2 kB - 32 kB),Oracle中的每个数据对象(如索引)都包含segment - &gt;范围 - &gt;块。因此索引的所有根,分支和叶子都存储在块中。如果条目数很小,则根块是叶块,并且没有分支。因此,在更大的范围内,您的描述是正确的。
如果扫描是并行的,则范围是连续的块范围,因此定义子范围不是问题,因此进程不会共享相同的数据。
多块读取是典型的,当数据不需要被读取排序时,您可以读取多个块(接近所需的块),并且与您只需要计算的示例查询一样。 / p>