全表扫描是 多块读
多块读 一次性 可以读128个块
要在 db里面 避免大事务
行迁移 单块读
select * from emp where rowid='AAA.......' 单快读
select * from emp where rowid >='AAA.......' 多快读
一个块里面的rowid是连续的,块与块之间也是连续的,一个区里面的rowid是连续的。
一: 索引扫描
索引分为两个大类
btree 索引 平衡树
等待事件:db file sequential read 但是你几乎看不到,因为只读一条数据
HINT 无需指定,有索引会自动走INDEX UNIQUE SCAN
root---branch ---leaf
2 层是 二院高度 blevel
1 branch
1 leaf
2.
INDEX RANGE SCAN 索引范围扫描。单块读 发生在对unique index/primary key 进行范围查找,
对non-unique index进行等值查找,范围查找
等待事件:db file sequential read 如果你监控某个SQL出现大量该等待事件,
有可能执行计划就有问题
HINT: INDEX(表名/别名 索引名)
cbo 认为返回的数据可能会超过1行,就会走索引范围扫描。
index range scan 只会扫描 部分叶子块
因为索引高度为 二元高度+1 这个二元高度包括root到第一个分支 所以访问索引叶子块数量= 索引高度-2
索引扫描是单块读,因为物理存储不连续。
select * from test where id<=1w; 扫描1w次 ,回表
作业: 把你认为走index range scan 可能是错的执行计划脚本抓取出来。
3.
含在where条件中,并且引导列基数很低。INDEX SKIP SCAN
一般来说只会返回少量数据,如果返回大量数据,说明该执
行计划可能有问题,也就是说索引建立不对。
等待事件:db file sequential read
HINT: INDEX_SS(表名/别名 索引名)
create index idx_owner_id on test(owner,id); 这样就会进行索引跳跃扫描,一般都会回表。
如果发现这种直接新建一个索引
作业: 把走了 INDEX SKIP SCAN 的sql抓取出来,重新建立索引。
4.
INDEX FULL SCAN (MIN/MAX) 索引最小/最大值扫描。单块读 通常发生在 select max(xxx) 或者
select min(xxx)并且xxx列上有索引。
等待事件:db file sequential read 我们几乎观察不到,因为只需读
取索引高度相同的index block数。
HINT 无需指定,有索引会自动走INDEX FULL SCAN(MIN/MAX)
select min(id) from test; 相当于 INDEX UNIQUE SCAN
5.
INDEX FULL SCAN 索引全扫描。单块读 。它扫描的结果是有序的,因为索引是有序的。它通常发生在
下面几种情况(注意:即使SQL满足以下情况 不一定会走索引全扫描)
1. SQL语句有order by选项,并且order by 的列都包含
在索引中,并且order by 后列顺序必须和索引列顺序一致。
2. 在进行SORT MERGE JOIN的时候,如果要查询的列通过索
引就能获得,那就不必进行全表扫描了,另外也避免了排
序,因为INDEX FULL SCAN返回的结果已经排序。
3. 当查询中有GROUP BY,并且GROUP BY 的列包含在索引中。
等待事件:db file sequential read
HINT: INDEX(表名/别名 索引名)
table access by index rowid
index full scan 除非表小,不然这样的执行计划会死人的。
6.
INDEX FAST FULL SCAN 索引快速全扫描。多块读 。当SQL要查询的数据能够完全从索引中获得,那么
Oracle就不会走全表扫描了,就会走索引快速全
扫描。索引快速全扫描类似全表扫描,它可以多块
读,并且可以并行扫描。
等待事件:db file scattered read
HINT:INDEX_FFS(表名/别名 索引名)
7.
desc 这种需求的时候,可能会进行索引降
序范围扫描,这种情况多出现在于分页语
句上。后面的培训案例有分页语句的优化。
等待事件:db file squential read
HINT:INDEX_DESC(表名/别名 索引名)