原文链接: https://www.modb.pro/db/23255?cyn (阅读原文,提升阅读体验)
索引范围扫描就是按照根、枝、叶的顺序读取,然后根据读取到的满足条件的数据的ROWID回到表中读取数据,如果要查询的数据列包含在索引中那么就免去了回表这步骤。叶块的地址在枝块,枝块地址在根块。找到枝块就可以找到叶块,找到根块就可以找到枝块。那么,如何找到根块呢?
其实很简单,在Oracle中,根块永远在索引段头的下一个块处。因此,索引扫描是不必读取索引段头的。先在数据字典表中找到段头位置,块号加1就是根块位置了。 接下来测试看看 –创建一个测试表
SQL> create table t11 as select * from dba_objects; Table created.
–创建索引
SQL> create index ind_t11 on t11(object_id); Index created.
–收集统计信息
SQL> exec dbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'T11',estimate_percent=>100,cascade=>true,method_opt=>'for all columns size auto',no_invalidate=>false); PL/SQL procedure successfully completed.
–查看索引信息
SQL> select table_name,index_name,blevel,index_type,leaf_blocks from dba_indexes where index_name='IND_T11' and table_name='T11'; TABLE_NAME INDEX_NAME BLEVEL INDEX_TYPE LEAF_BLOCKS ------------------------------ ------------------------------ ---------- --------------------------- ----------- T11 IND_T11 1 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.modb.pro/tag/oracle?cyn
编辑推荐:
- Oracle索引范围扫描操作流程简单介绍03-03
- 【DATAGUARD】Oracle19c Data Guard Broker03-03
- Oracle 创建PDB-Plugging In an Unplugged PDB03-03
- oracle表空间的整理03-03
- oracle并行相关的parallel_max_server参数03-03
- alert日志中出现Private Strand Flush Not Complete的处理方法03-03
- ORACLE RAC开启归档的正确姿势与ORA-0112603-03
- Oracle基本数据类型存储格式浅析——日期类型TIMESTAMP WITH TIME ZONE03-03
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- Oracle 创建PDB-Plugging In an Unplugged PDB
- oracle表空间的整理
oracle表空间的整理
26-03-03 - oracle并行相关的parallel_max_server参数
oracle并行相关的parallel_max_server参数
26-03-03 - alert日志中出现Private Strand Flush Not Complete的处理方法
- ORACLE RAC开启归档的正确姿势与ORA-01126
ORACLE RAC开启归档的正确姿势与ORA-01126
26-03-03 - 诊断 ORA-27300 ORA-27301 ORA-27302 错误 (文档 ID 2179478.1)
- undo的extend和steal机制
undo的extend和steal机制
26-03-03 - Oracle 11G数据库单实例安装
Oracle 11G数据库单实例安装
26-03-03 - ZDBM:靠谱的备份方案,听听专家怎么说
ZDBM:靠谱的备份方案,听听专家怎么说
26-03-03 - 如何诊断 ’library cache: mutex X’ 等待
如何诊断 ’library cache: mutex X’ 等待
26-03-03
