Oracle索引跳跃式扫描

索引跳跃式扫描
当一个查询未在where子句的谓词中指定复合索引的前导列,查询“跳过”该列时,就会发生索引跳跃式扫描。数据库将一个复合索引拆分成多个逻辑子索引。复合索引前导列中的不同值越少,组成复合索引的其他键的不同值越多,索引跳跃式扫描的性能就越好。例如,如果前导列有三个不同值,数据库将把复合索引拆分成三个逻辑子索引,并在其中搜索索引非前导列的值。

在下面的例子中,数据库使用了复合索引test_i1,它是在列(b,c)上创建的。查询指定的条件是”c<10″。查询的where子句没有使用复合索引的前导列(b),从而跳过该列。

SQL> select * from test where c<10;

         A B                   C
---------- ---------- ----------
         0 F                   1
         0 F                   2
         0 F                   3
         0 F                   4
         0 F                   5
         0 F                   6
         0 F                   7
         0 F                   8
         0 F                   9

9 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 650436733

-----------------------------------------------------------------------------------------------
| Id  | Operation                           | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |         |     9 |    90 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TEST    |     9 |    90 |     1   (0)| 00:00:01 |
|*  2 |   INDEX SKIP SCAN                   | TEST_I1 |     9 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("C"<10)
       filter("C"<10)

数据库把复合索引拆分成多少逻辑子索引,取决于前导列的不同值数量。在这个例子中,复合索引的前导列b只有极少数不同的值:

SQL> select distinct b from test;

B
----------
M
F

正如输出结果所显示的,复合索引的前导列只有两个不同的值。数据库把复合索引(b,c)拆分成两个子索引,第一个子索引的键值是”M”,而第二个子索引的键值是”2″。数据库检索第一个子索引,然后检索第二个子索引。另外,索引的非前导列c有200000个不同的值(与表中的行数据相同)。在这样的情况下,由于复合索引前导列中的不同值很少,数据库将采用复合索引跳跃式扫描,而不是像在以前版本的数据库(也就是说,Oracle 9i以前的版本)中那样执行全表扫描。

发表评论

电子邮件地址不会被公开。