oracle 基础知识(十四)----索引扫描
(1)索引唯一扫描(index unique scan)
通过唯一索引查找一个数值经常返回单个ROWID。如果该唯一索引有多个列组成(即组合索引),则至少要有组合索引的引导列参与到该查询中,如创建一个索引:create index idx_test on emp(ename, deptno, loc)。则select ename from emp where ename = ‘JACK’ and deptno = ‘DEV’语句可以使用该索引。如果该语句只返回一行,则存取方法称为索引唯一扫描。而select ename from emp where deptno = ‘DEV’语句则不会使用该索引,因为where子句种没有引导列。如果存在UNIQUE 或PRIMARY KEY 约束(它保证了语句只存取单行)的话,Oracle经常实现唯一性扫描。
为了方便查看设置执行计划为只显示执行计划
SQL> set autot traceonly exp; SQL> select * from scott.emp t where t.empno=10;Execution Plan ---------------------------------------------------------- Plan hash value: 2949544139--------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time|--------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 38 | 1 (0)| 00:00:01 || 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 38 | 1 (0)| 00:00:01 ||* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| 00:00:01 |-------------------------------------------------------------------------------------- Predicate Information (identified by operation id): ---------------------------------------------------2 - access("T"."EMPNO"=10)SQL>
(2)索引范围扫描(index range scan)
使用一个索引存取多行数据,同上面一样,如果索引是组合索引,而且select ename from emp where ename = ‘JACK’ and deptno = ‘DEV’ 语句返回多行数据,虽然该语句还是使用该组合索引进行查询,可此时的存取方法称为索引范围扫描。
在唯一索引上使用索引范围扫描的典型情况下是在谓词(where限制条件)中使用了范围操作符(如>、<、<>、>=、<=、between)
SQL> select empno,ename from scott.emp where empno > 6666 order by empno;Execution Plan ---------------------------------------------------------- Plan hash value: 169057108-------------------------------------------------------------------------------- ------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time|-------------------------------------------------------------------------------- ------| 0 | SELECT STATEMENT | | 14 | 140 | 2 (0)| 00:0 0:01 || 1 | TABLE ACCESS BY INDEX ROWID| EMP | 14 | 140 | 2 (0)| 00:0 0:01 ||* 2 | INDEX RANGE SCAN | PK_EMP | 14 | | 1 (0)| 00:0 0:01 |-------------------------------------------------------------------------------- ------ Predicate Information (identified by operation id): ---------------------------------------------------2 - access("EMPNO">6666)
在非唯一索引上,谓词可能返回多行数据,所以在非唯一索引上都使用索引范围扫描。
使用index rang scan的3种情况:
(a) 在唯一索引列上使用了range操作符(> < <> >= <= between)。
(b) 在组合索引上,只使用部分列进行查询,导致查询出多行。
(c) 对非唯一索引列上进行的任何查询。
(3)索引全扫描(index full scan)
与全表扫描对应,也有相应的全Oracle索引扫描。在某些情况下,可能进行全Oracle索引扫描而不是范围扫描,需要注意的是全Oracle索引扫描只在CBO模式下才有效。 CBO根据统计数值得知进行全Oracle索引扫描比进行全表扫描更有效时,才进行全Oracle索引扫描,而且此时查询出的数据都必须从索引中可以直接得到。
SQL> create index big_emp on scott.emp(empno,ename); ---创建索引Index created.SQL> select empno, ename from scott.emp order by empno,ename; 执行计划查看你 Execution Plan ---------------------------------------------------------- Plan hash value: 322359667---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | 140 | 1 (0)| 00:00:01 | | 1 | INDEX FULL SCAN | BIG_EMP | 14 | 140 | 1 (0)| 00:00:01 | ----------------------------------------------------------------------------
(4)索引快速扫描(index fast full scan)
扫描索引中的所有的数据块,与 index full scan很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间。
测试表创建: ---资源来自>>
create table t as select * from dba_objects where 1=2;insert into t select * from dba_objects where object_id is not null;创建一个索引 create index i_t_object_id on t(object_id);select object_id from t;set autot trace exp; -- 设置格式 查询:select object_id from t; Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873-------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 89550 | 1136K| 336 (1)| 00:00:05 | | 1 | TABLE ACCESS FULL| T | 89550 | 1136K| 336 (1)| 00:00:05 | -------------------------------------------------------------------------- Note ------ dynamic sampling used for this statement (level=2)这个好像走的是全表呀...由于我们需要查询的列为object_id,因此理论上只需要读取索引就应该可以返回所有数据,而此时为什么是全表扫描呢?这是因为NULL值与索引的特性所决定的。即null值不会被存储到B树索引。因此应该为表 t 的列 object_id 添加 not null 约束。alter table t modify(object_id not null); 添加约束再次查看SQL> select object_id from t;Execution Plan ---------------------------------------------------------- Plan hash value: 2036340805-------------------------------------------------------------------------------- ------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time|-------------------------------------------------------------------------------- ------| 0 | SELECT STATEMENT | | 89550 | 1136K| 53 (0)| 00:0 0:01 || 1 | INDEX FAST FULL SCAN| I_T_OBJECT_ID | 89550 | 1136K| 53 (0)| 00:0 0:01 |-------------------------------------------------------------------------------- ------ Note ------ dynamic sampling used for this statement (level=2)INDEX FAST FULL SCAN类似于full table scan,使用该方式当在高速缓存中没有找到所需的索引块时,则根据db_file_multiblock_read_count的值进行多块读操作。对于索引的分支结构只是简单的获取,然后扫描所有的叶结点。其结果是导致索引结构没有访问,获取的数据没有根据索引键的顺序排序。INDEX FAST FULL SCAN使用multiblock_read,故产生db file scattered reads 事件
Execution Plan
----------------------------------------------------------
Plan hash value: 431110666
--------------------------------------------------------------------------------
--
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
--------------------------------------------------------------------------------
--
| 0 | SELECT STATEMENT | | 89550 | 1136K| 194 (1)| 00:00:03
|
| 1 | INDEX FULL SCAN | I_T_OBJECT_ID | 89550 | 1136K| 194 (1)| 00:00:03
|
--------------------------------------------------------------------------------
--
Note
-----
- dynamic sampling used for this statement (level=2)
与INDEX FAST FULL SCAN所不同的是,INDEX FULL SCAN会完全按照索引存储的顺序依次访问整个索引树。当访问到叶结点之后,按照双向
链表方式读取相连节点的值。换言之,对于索引上所有的数据是按照有序的方式来读取的。如果索引块没有在高速缓存中被找到时,则需要从数
据文件中单块进行读取。对于需要读取大量数据的全索引扫描而言,这将使其变得低效。INDEX FULL SCAN使用single read,故产生
db file sequential reads事件。新版的Oracle支持db file parallel reads方式。
(5)索引跳跃扫描(INDEX SKIP SCAN)
INDEX SKIP SCAN,发生在多个列建立的复合索引上,如果SQL中谓词条件只包含索引中的部分列,并且这些列不是建立索引时的第一列时,就可能发生INDEX SKIP SCAN。这里SKIP的意思是因为查询条件没有第一列或前面几列,被忽略了。
例子来自于>>>
SQL> create table employee(gender varchar2(1),employee_id number);Table created.SQL> alter table employee modify(employee_id not null);Table altered.SQL> create index idx_employee on employee(gender,employee_id);Index created.SQL> beginfor i in 5001..10000 loopinsert into employee values ('M',i);end loop;commit;end; SQL> /PL/SQL procedure successfully completed.SQL> beginfor i in 1..5000 loopinsert into employee values ('F',i);end loop;commit;end; SQL> /PL/SQL procedure successfully completed.SQL> analyze table EMPLOYEE compute statistics for table for all columns for all indexes;Table analyzed.SQL> select * from employee where employee_id = 100;Execution Plan ---------------------------------------------------------- Plan hash value: 461756150-------------------------------------------------------------------------------- -| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-------------------------------------------------------------------------------- -| 0 | SELECT STATEMENT | | 1 | 4 | 3 (0)| 00:00:01 ||* 1 | INDEX SKIP SCAN | IDX_EMPLOYEE | 1 | 4 | 3 (0)| 00:00:01 |-------------------------------------------------------------------------------- -Predicate Information (identified by operation id): ---------------------------------------------------1 - access("EMPLOYEE_ID"=100)filter("EMPLOYEE_ID"=100)SQL>
转载于:https://www.cnblogs.com/kingle-study/p/10490461.html
oracle 基础知识(十四)----索引扫描相关推荐
- 物流基础知识(十四)
铁路货物运输的种类 铁路货物运输分为三种: 1. 整车运输:2. 零担运输: 3. 集装箱运输. 其中还包括快运,整列行包快运,但现在开展的范围不大. 一批货物的重量.体积或形状需要以一辆以上货车运输 ...
- ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
要啥自行车,直接看手表 //返回基元类型public string Get(){return "hello world";} //返回复杂类型public Person Get() ...
- 基础知识(十四)服务器搭建
1.到阿里云.或者腾讯云购买服务器 2.远程登陆:ssh ubuntu@123.206.84.91 (此ip地址是你所购买的服务器的外网IP地址) 3.远程数据传送:-r ServerVersion ...
- Oracle 基础知识——客户端连接oracle数据库服务端的四种方法
Oracle基础知识 Oracle Database 11g 快捷版 (Oracle Database XE) 是一款基于 Oracle Database 11g 第 2 版代码库的小型入门级数据库, ...
- Oracle基础知识之synonym(同义词)、database link(数据库链接)、数据完整性
Oracle基础知识之同义词.数据库链接.数据完整性 一.同义词 (一)概念 (二)分类 1.私有同义词 2.公共同义词 3.远程同义词 (三)作用 二.数据库链接 (一)概念 (二)分类 1.私有数 ...
- oracle:oracle基础知识(二)
oracle基础知识(二)笔记:高级查询 文章目录 分组查询 多属性分组语法: 过滤查询 group by 语句增强 sqlplus报表功能 多表查询 等值连接 外连接 自连接 子查询 子查询中的空值 ...
- oracle基础知识文档,Oracle 基础知识分享PPT
因测试组需求,所以把Oracle基础知识整理成了PPT,并讲解了一下(PPT无风格,简约派吐舌头). Oracle 是以高级结构化查询语言(SQL)为基础的大型关系数据库,通俗地讲它是用方便逻辑管理的 ...
- Java SE基础(十四)常用API
Java SE基础(十四)常用API 概述 Object类 构造方法 成员方法 toString()方法 equals(Object obj)方法 Arrays排序 Arrays类概述 Arrays成 ...
- [转]SQL Server 索引基础知识(2)----聚集索引,非聚集索引
SQL Server 索引基础知识(2)----聚集索引,非聚集索引 [来自]http://blog.joycode.com/ghj/archive/2008/01/02/113291.aspx 由于 ...
- Oracle入门(十四)之PL/SQL
一.PL/SQL 基本语法 PL/SQL语言是模块式的过程化SQL,是oracle公司对SQL的扩展. (1) (2) (3) (5) (6) (7)数据类型 Number 数字型 Varchar2 ...
最新文章
- 深度学习三巨头共同发文,聊聊深度学习的过去、现在与未来
- php向页面中添加数据_PHP创建文件,并向文件中写入数据,覆盖,追加的实现代码...
- 图形显卡_显卡缺货?专业图形卡主机方案演示,Quadro P2200
- python计算直角三角形顶点坐标
- [POJ]Zipper[动态规划]
- 【Python CheckiO 题解】Speech Module
- windows server 2019 服务器搭建的方法步骤(图文)
- stl之map容器的原理及应用
- 数据中心断路器整定值计算(二)
- Python数据探索性分析和预处理
- ASPack压缩可执行文件
- Python简洁出入库系统(批量出入库)
- NUKED数值表生成
- power supply frameware 框架
- win10企业版激活(自测有效)
- SPI通信拓扑如何选择?
- 小米10开始抓取日志怎么关闭_小米10手机降价,原因原来在这里
- 研磨设计模式之装饰模式-3
- plsql导出导入一张表的数据
- 解析数字孪生城市的四大特点