在Oracle中,如果我对2列做一个复合索引,那么在什么情况下这个索引会被用来查找记录呢?

In Oracle, if I make a composite index on 2 columns, then in which situation this index will be used to search the record?

在Oracle中,如果我在2列上做一个复合索引,那么在什么情况下这个索引将被用来搜索记录?

a) 如果我的查询有一个涉及第一列的 WHERE 子句 例如其中 first_column = 'John'

b) 如果我的查询有一个涉及第二列的 WHERE 子句 例如其中 second_column = 'Sharma'

c) a 或 b

d) a 和 b

e) 不是特别是这两列,而是 WHERE 子句中的任何列。

f) 仅 a 列或 a 和 b 列都

优化器将在多种情况下使用索引。即使不是"perfect".

最理想的情况是,如果您使用索引中的第一列进行查询,那么将使用索引。即使你只引用第一列,如果优化器认为它过滤掉了足够的数据,它仍然会使用索引。 如果索引列不满足查询要求(例如只引用 where 子句中的第二列),优化器仍然可以使用索引进行完整 (table) 索引扫描,如果它包含所有所需数据,因为索引小于完整 table.

在您的示例中,如果您仅从那个 table 进行查询,并且您只有一个索引,(a) 将使用该索引,(b) 如果您仅查询列,则将使用它在索引中,而 table 本身有更多。

如果您有其他索引,或加入其他 tables,那么这可能会完全影响解释计划。

查看 http://docs.oracle.com/cd/B19306_01/server.102/b14231/indexes.htm

我碰巧认为 MySQL 很好地描述了如何使用复合索引。文档是 here.

基本思想是,索引通常在以下情况下使用:

  • where条件等于col1时(col1 = value)。
  • where 条件为不等式或 col1 上的 in (col1 in (list), col1 < value)
  • where 条件等于 col1col2 时,通过 and (col1 = val1 and col2 = val2)
  • 连接
  • where 条件在 col1 上为等式且在 col2 上为不等式或 in
  • 以上四种情况中的任何一种,其中使用附加列并在其他列上附加条件,由 and 连接。

此外,如果 col1col2 是查询中唯一引用的列,则通常会使用索引。这称为覆盖索引,并且——假设 table 中还有其他列——读取索引比原始 table 更快,因为索引较小。

Oracle 有一个非常智能的优化器,因此它也可能在某些相关情况下使用索引,例如当 col1 使用 in 条件以及 col2 条件时.

一般来说,如果列是函数的参数,则条件不符合索引条件。因此,这些子句不会使用基本索引:

where month(col1) = 3
where trunc(col1) = trunc(sysdate)
where abs(col1) < 1

Oracle 支持函数式索引,因此如果这些结构确实很重要,您可以在 month(col1)trunc(col1)abs(col1).

上创建索引

此外,or 倾向于降低使用索引的可能性。

d) a 或 b

如果使用前导列,Oracle 可能会使用常规索引范围扫描并忽略未使用的列。

如果使用非前导列,Oracle 可以使用 index skip scan。在实践中,跳过扫描并不经常使用。


这里有两个完全不同的问题:什么时候可以Oracle使用索引和什么时候Oracle使用索引。上面解释了 Oracle can 在任何一种情况下都使用索引,您可以使用提示进行测试:/*+ index(table_name index_name) */.

确定 Oracle 使用索引的时间要复杂得多。 Oracle 将多块读取用于全 table 扫描和快速全索引扫描,将单块读取用于其他索引扫描。这意味着完整 table 扫描在读取较大百分比的数据时效率更高。但是涉及到很多因素:数据的百分比、索引有多大、告诉 Oracle 单块和多块 IO 有多快的系统统计信息、不同值的数量(对于选择跳过扫描尤其重要) ,索引聚类因子(table 按索引列排序)等