题
如果我按顺序在列(A、B、C)上创建索引,我的理解是,即使我仅在(A)、或(A 和 B)、或( A 和 B 和 C),但如果我只搜索 (B)、或 (C) 或 (B 和 C),则不会。它是否正确?
解决方案
当谓词放置在索引的非前导列上时,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
我最常看到“野外”的快速完整索引扫描,但一切都是可能的。
其他提示
这是不正确的。最好总是提出一个代表您的数据的测试用例并亲自查看。如果你想真正了解 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)
最高版本 Oracle 8 除非第一列包含在 SQL 中,否则永远不会使用索引。
在 Oracle 9i 中 跳过扫描索引访问 引入了该功能,即使前缀列不可用,Oracle CBO 也可以尝试使用索引。
此处很好地概述了跳跃扫描的工作原理: http://www.quest-pipelines.com/newsletter-v5/1004_C.htm