为什么搜索索引具有对数复杂度?

时间:2010-03-15 11:54:39

标签: database

索引与字典不相似吗?如果您有密钥,可以立即访问它吗?

显然索引有时会存储为B-Trees ......为什么会这样?

7 个答案:

答案 0 :(得分:8)

字典不是隐式排序的,B-Tree是。

B-Tree索引可用于远程访问,如下所示:

WHERE col1 BETWEEN value1 AND value2

或订购,如下:

ORDER BY col1

您无法立即访问B-Tree索引中的页面:您需要遍历编号以对数方式增加的子页面。

某些数据库也支持字典类型索引,即HASH索引,在这种情况下搜索时间是不变的。但是这些索引不能用于远程访问或排序。

答案 1 :(得分:4)

数据库索引通常(几乎总是)存储为B树。并且所有平衡树结构都具有用于搜索的O(log n)复杂度。

'Dictionary'是'抽象数据类型'(ADT),即它是一个不指定实现的功能描述。一些字典可以使用Hashtable进行O(1)查找,其他字典可以使用树并实现O(log n)。

数据库使用B-trees(超过任何其他类型的树)的主要原因是B树是自平衡的并且非常“浅”(需要很少的磁盘I / O)

答案 2 :(得分:3)

您可以使用密钥立即访问的唯一数据结构之一是向量,对于大量数据,当您开始插入和删除元素时,该向量将变得低效。它还需要连续的内存分配。

哈希可以很有效但需要更多空间并最终会发生冲突。

B树在搜索性能和空间之间有很好的平衡。

答案 3 :(得分:2)

如果您的唯一查询是等式测试,那么它的真实字典是一个不错的选择,因为它们将在摊销的O(1)时间内进行查找。但是,如果您想扩展查询以涉及范围检查,例如(select * from students where age > 10),那么您的字典突然完全失去了优势。这就是基于树的索引的来源。使用基于树的索引,您可以执行对数时间的等式和范围检查。

天真树结构存在一个问题。它们变得不平衡,这意味着在向索引添加某些值之后,树结构变得不平衡(例如长行)并且查找开始再次花费O(N)时间。这可以通过平衡树来解决。 B-Tree就是这样一种方法,它也利用了能够执行大块I / O的系统,因此最适合数据库。

答案 4 :(得分:1)

hashindex(例如,在mysql和postgres中)具有用于搜索的恒定复杂度(O(1))。

 CREATE INDEX ... USING HASH 

答案 5 :(得分:1)

如果您为数组预先分配 N 条目,并且哈希是此的密钥,则可以实现O(1) N 值。

但是如果你存储了超过N个条目,那么就会发生碰撞。因此,对于数组中的每个键,您都有一个值列表。所以它不再是O(1)了。扫描列表本身将是O(m),其中m是平均碰撞次数。

Example with hash = n mod 3
0  -->  [0,a] [3,b] ...
1  -->  [1,a] [4,b] [7,b] ...
2  -->  [2,a] [5,b] ...

在某个时间点,与使用O(log n)查找时间的其他结构相比,您花费更多时间遍历潜在密钥的值列表会变得更糟糕,其中n是条目的总数。 / p>

你当然可以选择 N ,以至于数组/哈希比B-Tree更快。但是阵列具有固定的预分配大小。因此,如果 N = 1000且存储3个值,则会浪费数组中的997个插槽。

所以它基本上是一个性能空间权衡。对于一小组值,array和散列非常好。对于大量值,B-Tree效率最高。

答案 6 :(得分:1)

哈希是最快的查找数据结构,但有一些问题:

a)未分类 b)无论散列有多好,都会发生冲突,这在大量数据时会出现问题 c)在哈希索引文件中查找哈希值需要很长时间,因此大多数时间哈希仅对内存(RAM)数据有意义 - 这使得它们不适合数据库 - 大多数时候都不适合所有数据库RAM中的数据

排序树解决了这些问题,特别是b-tree操作可以使用文件有效地实现。唯一的缺点是它们作为哈希结构的查找时间较慢。

在所有情况下,没有数据结构是完美的,取决于估计的数据大小以及如何使用它,一个更好。