20

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

4

3 回答 3

14

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

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

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

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

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

于 2008-09-15T20:25:04.670 回答
9

这是不正确的。总是最好拿出一个代表您的数据的测试用例并亲自查看。如果你想真正了解 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)
于 2008-09-12T15:47:58.950 回答
5

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

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

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

于 2008-09-15T12:46:25.367 回答