数据库索引及其Big-O表示法

时间:2011-01-14 18:31:32

标签: sql database sqlite indexing big-o

我试图用Big-O表示法来理解数据库索引的性能。如果不了解它,我会猜测:

  • 查询主键或唯一索引将为您提供O(1)查找时间。
  • 查询非唯一索引也会给出O(1)时间,尽管可能'1'比唯一索引慢(?)
  • 查询没有索引的列将提供O(N)查找时间(全表扫描)。

这一般是正确的吗?查询主键会不会比O(1)表现更差?我特别关注SQLite,但我有兴趣了解不同数据库之间的差异程度。

5 个答案:

答案 0 :(得分:25)

大多数关系数据库将索引结构化为B树。

如果表具有聚类索引,则数据页将存储为B树的叶节点。从本质上讲,聚类索引就成了表格。

对于没有聚类索引的表,表的数据页存储在堆中。任何非聚集索引都是B树,其中B树的叶节点标识堆中的特定页面。

B树的最坏情况高度为O(log n),并且由于搜索取决于高度,因此B树查找的运行方式类似于(平均值)

O(log t n)

其中t是最小化因子(每个节点必须至少有 t -1个键,最多2 * t * -1个键(例如,2 * t *个子)。

这就是我理解它的方式。

当然,不同的数据库系统可能会使用不同的数据结构。

当然,如果查询不使用索引,则搜索是对包含数据页的堆或B树的迭代。

如果使用的索引可以满足查询,则搜索会便宜一些;否则,需要在内存中获取相应的数据页面。

答案 1 :(得分:5)

索引查询(唯一或不唯一)更典型地是O(log n)。非常简单,你可以认为它类似于排序数组中的二进制搜索。更准确地说,它取决于索引类型。但是,例如,b树搜索仍然是O(log n)。

如果没有索引,那么,是的,它是O(N)。

答案 2 :(得分:2)

如果您选择相同的列,则搜索

  • Primary或​​Unqiue将为O(log n):这是一个b-tree搜索
  • 非唯一索引也是O(log n)+一点:这是一个b树搜索
  • 无索引= O(N)

如果您需要来自其他“来源”(索引交集,书签/密钥查找等)的信息,因为索引是非覆盖的,那么您可以有O(n + log n)或O(log n + log n + log n)因为多个索引命中+中间排序。

如果统计数据显示您需要高百分比的行(例如,不是非常有选择性的索引),那么索引可能会被忽略并变为scan = O(n)

答案 3 :(得分:2)

其他答案给出了一个很好的起点;但我只想补充一点来获得O(1),主索引本身需要基于哈希(这通常不是默认选择);所以更常见的是对数(B树)。

你是正确的,二级索引通常具有相同的复杂性,但实际性能更差 - 这是因为索引和数据没有聚集,所以常量(磁盘搜索次数)更大。

答案 4 :(得分:2)

这取决于您的查询。

  • 形式Column = Value的条件允许使用基于散列的索引,该索引具有O(1)查找时间。但是,many databases, including SQLite, do not support them
  • 使用关系运算符(<><=>=)的条件可以使用有序索引,通常使用二叉树实现,该索引具有O(log n)查找时间。
  • 不能使用索引的更复杂的表达式需要O(n)时间。

由于您主要对SQLite感兴趣,因此您可能希望阅读其Query Optimizer Overview,其中更详细地解释了如何选择索引。