本篇内容主要讲解“Oracle索引范围扫描操作流程是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Oracle索引范围扫描操作流程是什么”吧!

索引范围扫描就是按照根、枝、叶的顺序读取,然后根据读取到的满足条件的数据的ROWID回到表中读取数据,如果要查询的数据列包含在索引中那么就免去了回表这步骤。叶块的地址在枝块,枝块地址在根块。找到枝块就可以找到叶块,找到根块就可以找到枝块。那么,如何找到根块呢?

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

SQL>createtablet11asselect*fromdba_objects;Tablecreated.

–创建索引

SQL>createindexind_t11ont11(object_id);Indexcreated.

–收集统计信息

SQL>execdbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'T11',estimate_percent=>100,cascade=>true,method_opt=>'forallcolumnssizeauto',no_invalidate=>false);PL/SQLproceduresuccessfullycompleted.

–查看索引信息

SQL>selecttable_name,index_name,blevel,index_type,leaf_blocksfromdba_indexeswhereindex_name='IND_T11'andtable_name='T11';TABLE_NAMEINDEX_NAMEBLEVELINDEX_TYPELEAF_BLOCKS------------------------------------------------------------------------------------------------------------T11IND_T111NORMAL161

–执行一个简单查询查看执行计划

SQL>select*fromtable(dbms_xplan.display_cursor('','','allstatslast'));PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------SQL_IDg7411gwcvppnd,childnumber0-------------------------------------select*fromt11whereobject_id=11Planhashvalue:469757982-------------------------------------------------------------------------------------------------|Id|Operation|Name|Starts|E-Rows|A-Rows|A-Time|Buffers|-------------------------------------------------------------------------------------------------|0|SELECTSTATEMENT||1||1|00:00:00.01|4||1|TABLEACCESSBYINDEXROWID|T11|1|1|1|00:00:00.01|4||*2|INDEXRANGESCAN|IND_T11|1|1|1|00:00:00.01|3|-------------------------------------------------------------------------------------------------PredicateInformation(identifiedbyoperationid):---------------------------------------------------2-access("OBJECT_ID"=11)19rowsselected.

从执行计划可以看到在索引范围扫描这一步消耗了3个逻辑读,而索引的层高为1,说明有两层
观察到的逻辑读为4。这4次逻辑读分别是:Root块一次,叶块两次,回表读取数据块一次。
叶块之所以需要两次,是因为索引是非唯一的。第一次读叶块是为了取出目标行ROWID,第二次读叶块是判断此叶块中还有没有满足条件的行。
如果建成了唯一索引,不需要判断叶块是否还有满足条件的行,叶块就只需要读一次,一共只需要3次逻辑读。

dropindexind_t11;SQL>dropindexind_t11;Indexdropped.createuniqueindexind_t11_1ont11(object_id);SQL>createuniqueindexind_t11_1ont11(object_id);Indexcreated.select*fromt11whereobject_id=11;SQL>select*fromtable(dbms_xplan.display_cursor('','','allstatslast'));PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------SQL_IDg7411gwcvppnd,childnumber0-------------------------------------select*fromt11whereobject_id=11Planhashvalue:645999193------------------------------------------------------------------------------------------------------------|Id|Operation|Name|Starts|E-Rows|A-Rows|A-Time|Buffers|Reads|------------------------------------------------------------------------------------------------------------|0|SELECTSTATEMENT||1||1|00:00:00.01|3|4||1|TABLEACCESSBYINDEXROWID|T11|1|1|1|00:00:00.01|3|4||*2|INDEXUNIQUESCAN|IND_T11_1|1|1|1|00:00:00.01|2|4|------------------------------------------------------------------------------------------------------------PredicateInformation(identifiedbyoperationid):---------------------------------------------------2-access("OBJECT_ID"=11)19rowsselected.

到此,相信大家对“Oracle索引范围扫描操作流程是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!