索引范围扫描的操作流程

索引范围扫描,网上已经有很多讨论了,就是按照根、枝、叶的顺序读取。叶块的地址在枝块,枝块地址在根块。找到枝块就可以找到叶块,找到根块就可以找到枝块。那么,如何找到根块呢?

These two terms in the Predicate Information section indicate when the
data source is reduced. Simply, access means only retrieve those records
meeting the condition and ignore others. Filter means *after* you
already got the data, go through them all and keep those meeting the
condition and throw away the others.

其实很简单,在 Oracle
中,根块永远在索引段头的下一个块处。因此,索引扫描是不必读取索引段头的。先在数据字典表中找到段头位置,块号加
1 就是根块位置了。

access: 直接获取那些满足条件的数据,抛弃其他不满足的数据
filter:
你已经有了一些数据,对这些已经有的数据应用filter,得到满足filter的数据。

对索引范围扫描时的逻辑读,可以做如下测试:

SQL insert into table1 select rownum,abcde from dba_objects;

 

12691 rows created.

一:简要说明

SQL commit;

在查看执行计划的信息中,经常会看到两个谓词filter和access,它们的区别是什么,理解了这两个词对我们解读Oracle的执行计划信息会有所帮助。

Commit complete.

简单说,执行计划如果显示是access,就表示这个谓词条件的值将会影响数据的访问路径(表还是索引),而filter表示谓词条件的值并不会影响数据访问路径,只起到过滤的作用。

SQL create index table1_id on table1(id) tablespace tbs_ts1;

二:举例说明
SQL> create table zhou_t (x int , y int );
表已创建。
SQL> set autotrace trace exp;
SQL> select /*+rule*/ * from zhou_t where x=5;

Index created.

执行计划

SQL exec dbms_stats.gather_table_stats(LHB,TABLE1);

Plan hash value: 1395150869

PL/SQL procedure successfully completed.

| Id | Operation | Name |

| 0 | SELECT STATEMENT | |

SQL select BLEVEL from dba_INDEXES where index_name=TABLE1_ID and
owner=LHB;

|* 1 | TABLE ACCESS FULL| ZHOU_T |

BLEVEL

Predicate Information (identified by operation id):

1 – filter(“X”=5)


澳门新葡亰手机版,Note

  • rule based optimizer used (consider using cbo)

因为表zhou_t没有创建索引,执行计划没有选择数据访问路径的余地,谓词条件在这里只是起到数据过滤的作用,所以使用了filter

如果在表上创建了索引呢?

SQL> create index zhou_t_idx on zhou_t(x,y);
索引已创建。
SQL> select /*+rule*/ * from zhou_t where x=5;

1

执行计划

上面先向表中插入了 10000 多行,再创建了一个 1 层高的索引,索引只有 Root
块和叶块。

Plan hash value: 42197324

| Id | Operation | Name |

| 0 | SELECT STATEMENT | |

|* 1 | INDEX RANGE SCAN| ZHOU_T_IDX |

Predicate Information (identified by operation id):

1 – access(“X”=5)

Note

  • rule based optimizer used (consider using cbo)

从上面可以看到,谓词条件影响到数据访问的路径——选择了索引,所以用access

 

SQL> create table t
  2  as select rownum r,object_name
  3  from dba_objects
  4  /
Table created.
SQL> create index t_idx on t(r);
Index created.
SQL> execute
dbms_stats.gather_table_stats(user,’t’,cascade=>true)
PL/SQL procedure successfully completed.
SQL> set autotrace traceonly explain
SQL> select * from t
  2  where r = 10000;