【问题标题】:Do indexes work in NOT IN or <> clause?索引在 NOT IN 或 <> 子句中有效吗?
【发布时间】:2016-08-13 20:36:50
【问题描述】:
我读过(至少 Oracle)数据库中的普通索引基本上是 B-树结构,因此存储处理适当根节点的记录。 “小于”根的记录被迭代地存储在树的左侧,而“大于”根的记录被存储在右侧。正是这种存储方法有助于通过树遍历加快扫描速度,因为深度和广度减少了。
但是,在创建索引或对where 子句进行性能调整时,大多数指南都谈到首先优先考虑要考虑相等的列(IN or = clause),然后单独移动到具有不等式子句的列。 (NOT IN, <>)。这个建议的原因是什么?使用树遍历来预测给定值不存在不像预测给定值存在那样容易吗?
索引不能与否定一起使用吗?
【问题讨论】:
标签:
sql
database
performance
indexing
【解决方案1】:
问题在于索引内的位置。如果您有两列在 col1 中有字母,在 col 2 中有数字,那么索引可能如下所示:
Ind col1 col2
1 A 1
2 A 1
3 A 1
4 A 2
5 B 1
6 B 1
7 B 2
8 B 3
9 B 3
10 C 2
11 C 3
(ind是索引中的位置。记录定位器被省略了。)
如果你在寻找col1 = 'B',那么你可以找到位置5,然后扫描索引直到位置9。如果你在寻找col1 <> 'B',那么你需要找到第一个不是'B'的记录扫描并重复之后的第一条记录。使用IN 和NOT IN,情况会变得更糟。
另外一个因素是,如果相对少数的记录满足相等条件,那么几乎所有记录都会失败——而且当几乎所有记录都需要读取时,索引通常没有用处。一个有时例外是聚集索引。
Oracle 比大多数数据库有更好的索引优化——它会从不同的位置开始进行多次扫描。即便如此,不等式对于索引的用处通常要小得多。