网站首页 > 技术文章 正文
一、 根据索引的类型与where限制条件的不同,有4种类型的Oracle索引扫描:
(1) 索引唯一扫描(index unique scan)
(2) 索引范围扫描(index range scan)
(3) 索引全扫描(index full scan)
(4) 索引快速扫描(index fast full scan)
[@more@]
1. 索引唯一扫描(index unique scan)
通过唯一索引查找一个数值经常返回单个ROWID。如果该唯一索引有多个列组成(即组合索引),则至少要有组合索引的引导列参与到该查询中,如创建一个索引:create index IDX_T_YSK_AJ_AJ_YSID on T_YSK_AJ_AJ (YSID) tablespaceTBS_YYK_YSKINDEX。则select * from t_ysk_aj_aj t where ysid='tangyun'语句可以使用该索引。如果该语句只返回一行,则存取方法称为索引唯一扫描。而select * from t_ysk_aj_aj t where csid='tangyun';语句则不会使用该索引,因为where子句种没有引导列。如果存在UNIQUE 或PRIMARY KEY 约束(它保证了语句只存取单行)的话,Oracle经常实现唯一性扫描。
2. 索引范围扫描(index range scan)
使用一个索引存取多行数据,同上面一样,如果索引是组合索引,而且select * from t_ysk_aj_aj t where ysid='tangyun'andcsid='tangyun';语句返回多行数据,虽然该语句还是使用该组合索引进行查询,可此时的存取方法称为索引范围扫描。
在唯一索引上使用索引范围扫描的典型情况下是在谓词(where限制条件)中使用了范围操作符(如>、<、<>、>=、<=、between)
在非唯一索引上,谓词可能返回多行数据,所以在非唯一索引上都使用索引范围扫描。
使用index rang scan的3种情况:
(1) 在唯一索引列上使用了range操作符(> < <> >= <= between)。
(2) 在组合索引上,只使用部分列进行查询,导致查询出多行。
(3) 对非唯一索引列上进行的任何查询。
3. 索引全扫描(index full scan)
与全表扫描对应,也有相应的全Oracle索引扫描。在某些情况下,可能进行全Oracle索引扫描而不是范围扫描,需要注意的是全Oracle索引扫描只在CBO模式下才有效。 CBO根据统计数值得知进行全Oracle索引扫描比进行全表扫描更有效时,才进行全Oracle索引扫描,而且此时查询出的数据都必须从索引中可以直接得到。
还是上面的例子:
SQL> explain plan for select count(ysid) from t_ysk_aj_aj;
Explained
SQL> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1790046257
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| T
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 0 (0)| 0
| 1 | SORT AGGREGATE | | 1 | 13 | |
| 2 | INDEX FULL SCAN| IDX_T_YSK_AJ_AJ_YSID | 1 | 13 | 0 (0)| 0
--------------------------------------------------------------------------------
9 rows selected
4. 索引快速扫描(index fast full scan)
扫描索引中的所有的数据块,与 index full scan很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间。
5. 查看执行计划的方法
在 sql*plus设置autotrace:
序号
命令
解释
1
SET AUTOTRACE OFF
此为默认值,即关闭Autotrace
2
SET AUTOTRACE ON EXPLAIN
只显示执行计划
3
SET AUTOTRACE ON STATISTICS
只显示执行的统计信息
4
SET AUTOTRACE ON
包含2,3两项内容
5
SET AUTOTRACE TRACEONLY
与ON相似,但不显示语句的执行结果
在pl/sql Developer工具
SQL> explain plan for select count(ysid) from t_ysk_aj_aj;
Explained
SQL> select * from table(dbms_xplan.display('PLAN_TABLE'));
二、 解读执行计划
1. Cardinality(基数)/ rows
Cardinality的值对于CBO做出正确的执行计划来说至关重要。 如果CBO获得的Cardinality值不够准确(通常是没有做分析或者分析数据过旧造成),在执行计划成本计算上就会出现偏差,从而导致CBO错误的制定出执行计划。
Cardinality值表示CBO预期从一个行源(row source)返回的记录数,这个行源可能是一个表,一个索引,也可能是一个子查询。 在Oracle 9i中的执行计划中,Cardinality缩写成Card。 在10g中,Card值被rows替换。
在多表关联查询或者SQL中有子查询时,每个关联表或子查询的Cardinality的值对主查询的影响都非常大,甚至可以说,CBO就是依赖于各个关联表或者子查询Cardinality值计算出最后的执行计划。
对于多表查询,CBO使用每个关联表返回的行数(Cardinality)决定用什么样的访问方式来做表关联(如Nested loops Join 或hash Join)。
对于子查询,它的Cardinality将决定子查询是使用索引还是使用全表扫描的方式访问数据。
2. 执行计划中含义解释
ID:一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。
Operation: 当前操作的内容。
Rows: 当前操作的Cardinality,Oracle估计当前操作的返回结果集。
Cost(CPU):Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。
Time:Oracle 估计当前操作的时间。
Access:表示这个谓词条件的值将会影响数据的访问路劲(表还是索引)。
Filter:表示谓词条件的值不会影响数据的访问路劲,只起过滤的作用。
3. 执行计划中的统计信息
db block gets : 从buffer cache中读取的block的数量
consistent gets: 从buffer cache中读取的undo数据的block的数量
physical reads: 从磁盘读取的block的数量
redo size: DML生成的redo的大小
sorts (memory) :在内存执行的排序量
sorts (disk) :在磁盘上执行的排序量
猜你喜欢
- 2024-10-17 oracle数据库设计总结|三大范式 oracle数据库设计规范
- 2024-10-17 数据库(Oracle)序列(Sequence)的基本使用
- 2024-10-17 oracle日常巡检--检查数据库安全 oracle问题排查
- 2024-10-17 浅谈Oracle的执行计划 oracle执行计划sql
- 2024-10-17 [Oracle数据库] Oracle事务和常用数据对象
- 2024-10-17 SQL FOREIGN KEY 约束 sql语句的约束条件
- 2024-10-17 oracle每天做巡检时怎么检查数据库安全呢?
- 2024-10-17 Oracle与其他数据库的区别 oracle数据库和mysql区别
- 2024-10-17 Oracle项目管理系统之进度控制 oracle 项目管理软件
- 2024-10-17 一文搞懂Oracle 0 至 6 级锁(附案例详解)
你 发表评论:
欢迎- 05-11FANUC修改前端目录教程
- 05-11前端分享-Set你不知道的事
- 05-11jq+ajax+bootstrap改了一个动态分页的表格
- 05-11千万级大表分页查询效率剧降,你会怎么办?
- 05-11Elasticsearch深度分页
- 05-11如何写一个简单的分页
- 05-11手速太快引发分页翻车?前端竞态陷阱揭秘
- 05-11「linux」Socket缓存是如何影响TCP性能的?
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端懒加载 (45)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle约束 (46)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)