SQL/Oracle:当可以使用多列上的索引时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/57878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 01:27:58  来源:igfitidea点击:

SQL/Oracle: when indexes on multiple columns can be used

oracleindexing

提问by avernet

If I create an index on columns (A, B, C), in that order, my understanding is that the database will be able to use it even if I search only on (A), or (A and B), or (A and B and C), but not if I search only on (B), or (C), or (B and C). Is this correct?

如果我按顺序在列 (A, B, C) 上创建索引,我的理解是即使我只搜索 (A),或 (A 和 B),或 ( A 和 B 和 C),但如果我只搜索 (B)、或 (C) 或 (B 和 C),则不会。这样对吗?

采纳答案by David Aldridge

There are actually three index-based access methods that Oracle can use when a predicate is placed on a non-leading column of an index.

当谓词放在索引的非前导列上时,Oracle 实际上可以使用三种基于索引的访问方法。

i) Index skip-scan: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#PFGRF10105

i) 索引跳过扫描:http: //download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#PFGRF10105

ii) Fast full index scan: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i52044

ii) 快速全索引扫描:http: //download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i52044

iii) Index full scan: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i82107

iii) 索引全扫描:http: //download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i82107

I've most often seen the fast full index scan "in the wild", but all are possible.

我最常看到“在野外”进行快速全索引扫描,但一切皆有可能。

回答by Ethan Post

That is not correct. Always best to come up with a test case that represents your data and see for yourself. If you want to really understand the Oracle SQL Optimizer google Jonathan Lewis, read his books, read his blog, check out his website, the guy is amazing, and he always generates test cases.

那是不正确的。始终最好提出一个代表您的数据的测试用例并亲自查看。如果你想真正了解 Oracle SQL Optimizer google Jonathan Lewis,阅读他的书,阅读他的博客,查看他的网站,这个人很了不起,他总是生成测试用例。

create table mytab nologging as (
select mod(rownum, 3) x, rownum  y, mod(rownum, 3) z from all_objects, (select 'x' from user_tables where rownum < 4)
);

create index i on mytab (x, y, z);

exec dbms_stats.gather_table_stats(ownname=>'DBADMIN',tabname=>'MYTAB', cascade=>true);

set autot trace exp

select * from mytab where y=5000;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=10)
   1    0   INDEX (SKIP SCAN) OF 'I' (INDEX) (Cost=1 Card=1 Bytes=10)

回答by stuandgravy

Up to version Oracle 8an index will never be used unless the first column is included in the SQL.

在 Oracle 8 之前,除非 SQL 中包含第一列,否则永远不会使用索引。

In Oracle 9i the Skip Scan Index Accessfeature was introduced, which lets the Oracle CBO attempt to use indexes even when the prefix column is not available.

在 Oracle 9i中引入了跳过扫描索引访问特性,即使前缀列不可用,它也允许 Oracle CBO 尝试使用索引。

Good overview of how skip scan works here: http://www.quest-pipelines.com/newsletter-v5/1004_C.htm

这里很好地概述了跳过扫描的工作原理:http: //www.quest-pipelines.com/newsletter-v5/1004_C.htm