本文主要讲解“Oracle索引范围扫描的操作流程是什么”。感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习“Oracle索引范围扫描的操作流程是什么”!
索引扫描是按照根、枝、叶的顺序读取,然后根据符合条件的数据的ROWID返回表中读取数据。如果要查询的数据列包含在索引中,则省略返回表的步骤。叶地址在分支块中,分支块地址在根块中。如果找到分支块,就可以找到叶块;如果找到根块,就可以找到分支块。那么,如何找到根块呢?
实际上很简单,在Oracle中,根块总是在索引段头的下一个块。因此,索引扫描不需要读取索引段头。首先在数据字典表中找到段头位置,块号加1就是根块位置。
接下来我们来测试一下。
创建测试表。
SQLcreatetablet11asselect从dba_objects中选择*;
已创建。创建索引。
SQLcreateindexind _ t11 ont 11(object _ id);
索引已创建。收集统计数据。
sqlexedcbms _ stats . gather _ table _ stats(own name=' SCOTT ',tabname='T11 ',estimate_percent=100,cascade=true,method _ opt=' for llcolumnsizeauto ',no _ invalidate=false);
pl/sqlprocedrecessfully completed。查看索引信息。
SQLselecttable_name,index_name,blevel,index_type,leaf _ blocksfromdba _ indexes where index _ name=' IND _ T11 '和andtable _ name=' T11
表_名称索引_名称索引_类型叶_块
-
t11 ind _ t111 normal 161-执行一个简单的查询来查看执行计划。
>SQL> select * from table(dbms_xplan.display_cursor('','','allstats last'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID g7411gwcvppnd, child number 0
-------------------------------------
select * from t11 where object_id=11
Plan hash value: 469757982
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 4 |
| 1 | TABLE ACCESS BY INDEX ROWID| T11 | 1 | 1 | 1 |00:00:00.01 | 4 |
|* 2 | INDEX RANGE SCAN | IND_T11 | 1 | 1 | 1 |00:00:00.01 | 3 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=11)
19 rows selected.
从执行计划可以看到在索引范围扫描这一步消耗了3个逻辑读,而索引的层高为1,说明有两层
观察到的逻辑读为4。这4次逻辑读分别是:Root块一次,叶块两次,回表读取数据块一次。
叶块之所以需要两次,是因为索引是非唯一的。第一次读叶块是为了取出目标行ROWID,第二次读叶块是判断此叶块中还有没有满足条件的行。
如果建成了唯一索引,不需要判断叶块是否还有满足条件的行,叶块就只需要读一次,一共只需要3次逻辑读。
drop index ind_t11; SQL> drop index ind_t11; Index dropped. create unique index ind_t11_1 on t11(object_id); SQL> create unique index ind_t11_1 on t11(object_id); Index created. select * from t11 where object_id=11; SQL> select * from table(dbms_xplan.display_cursor('','','allstats last')); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID g7411gwcvppnd, child number 0 ------------------------------------- select * from t11 where object_id=11 Plan hash value: 645999193 ------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | ------------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 3 | 4 | | 1 | TABLE ACCESS BY INDEX ROWID| T11 | 1 | 1 | 1 |00:00:00.01 | 3 | 4 | |* 2 | INDEX UNIQUE SCAN | IND_T11_1 | 1 | 1 | 1 |00:00:00.01 | 2 | 4 | ------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_ID"=11) 19 rows selected.
到此,相信大家对“Oracle索引范围扫描操作流程是什么”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/68681.html