8 访问路径介绍--优化主题系列
2017-09-29 10:15
190 查看
8.1 tableaccess full
TABLE ACCESS FULL 全表扫描,多块读,等待事件:db file scattered read
如果是并行全表扫描,等待事件:direct path read
11g 有个新特征,在进行全表扫描的时候也会产生direct path read
在OLTP环境中要通过 10949event禁止该新特征
在OLAP环境中可以不用禁止
如果表上面有大量的行迁链接,会是单块读等待事件表现为db filesequential read
如果表上面发生了一个大事物,全表扫描会从UNDO读取前镜像,也会是单块读
HINT: FULL(表名/别名)
提问:假设test表有10GB的数据如果没有索引是不是走全表扫描??
select id from test where owner='SYS';
全表扫描是只扫描id和 owner列还是全扫??是不是
10GB的数据全部扫一遍??
高水位下的都扫对吧??这个时候可以看是不是碎片太多了??是不是经常DML碎片就多??
如果是并行全表扫描,等待事件:direct path read
8.2 rowidscan
ROWID SCAN 根据ROWID取得数据都是单块读
TABLEACCESS BY USER ROWID 直接用ROWID取得数据比如 whererowid='xxxxxx'
TABLEACCESS BY INDEX ROWID 通过索引的ROWID获得数据
提问:为什么通过ROWID回表是单块读??
ROWID是不是一条数据为了读一条数据读多个块合理吗??一个ROWID对应一个块
当然一个ROWID可能对应多个块行迁移
8.3 indexunique scan
INDEX UNIQUE SCAN 索引唯一扫描。单块读只可能发生在unique index/primary key等值查找
等待事件:db filesequential read但是你几乎看不到,因为只读一条数据
HINT 无需指定,有索引会自动走INDEXUNIQUE SCAN
OLAP这个很少见数据仓库不要主键一般不要建索引不然插入数据很慢
8.4 indexrange scan
INDEX RANGE SCAN 索引范围扫描。单块读 发生在对uniqueindex/primary key进行范围查找,对non-uniqueindex进行等值查找,范围查找
等待事件:db filesequential read如果你监控某个SQL出现大量该等待事件,有可能执行计划就有问题
HINT: INDEX(表名/别名索引名)
提问:索引唯一等值扫描需要几个I/O??
索引高度+1 如果存在行迁移则再+1
提问:非唯一索引等值扫描走什么访问路径??
不能判断是返回一条还是多条所以要走indexrange scan
节点的指针叫DBA(datablock address)
提问:为什么索引范围扫描是单块读??
索引是不是有root、branch、leafblock
leaf block之间是不是双向链表??在物理上是连续的吗??索引分裂就不连续了
有insert、update、delete
既然物理上存储不是连续的你能多块读吗??
提问:为什么indexfast full scan有能进行多块读??
索引也有段段由区组成 extent的数据块是不是连续的??
index fast full scan是根据extent来读的 这个时候肯定是多块读
只要通过双向链表扫描都是单块读
索引扫描中只有indexfast full scan才是多块读
是不是你们遇到过很多菜鸟拿到问题就说靠你这个都不走索引肯定慢啊
是不是有时候走索引反而更慢??是不是I/O扫描次数就多了??
SQL优化的核心思想是什么??较少物理I/O其次减少逻辑I/O
8.5 indexskip scan
exadata可以只扫描某个列smart scan
INDEX SKIP SCAN 索引跳跃扫描。单块读只可能发生在组合索引上,引导列(组合索引第一列)没有包含在where条件中,并且引导列基数很低。INDEXSKIP
SCAN一般来说只会返回少量数据,如果返回大量数据,说明该执行计划可能有问题,也就是说索引建立不对。
等待事件:db filesequential read
HINT: INDEX_SS(表名/别名索引名)
发生索引跳跃扫描的条件有哪些??
1. 必须是组合索引
2. 引导列基数很低
3. where条件中没有引导列
提问:为什么这里有个skip
关键字??
因为where条件里面没有引导列但还要去扫描索引
提问:如果where条件里有引导列那走什么??
index range scan 引导列出现在where条件中那么它怎么跳??肯定跳不了的
如果引导列基数很高可能就不会走indexskip scan了
提问:当执行计划中有indexskip scan还能优化吗??
直接建立一个索引不就完了干嘛非要扫描这个破索引呢??
select * from test where id=xx and tablespace=xx;
create index idx on test(owner,id,tablespace);
这个时候是不是可能走indexskip scan??
我直接创建这样的索引走范围扫描不就完了??
create index idx1 on test(id,tablespace);
8.6 indexfull scan
INDEX FULL SCAN 索引全扫描。单块读。它扫描的结果是有序的,因为索引是有序的。它通常发生在
下面几种情况(注意:即使SQL满足以下情况不一定会走索引全扫描)
1.SQL语句有order by选项,并且order by的列都包含在索引中,并且order
by后列顺序必须和索引列顺序一致。
2. 在进行SORTMERGE JOIN的时候,如果要查询的列通过索引就能获得,那就不必进行全表扫描了,另外也避免了排序,因为INDEXFULL
SCAN返回的结果已经排序。
3. 当查询中有GROUP BY,并且GROUP BY的列包含在索引中。
等待事件:db file sequential read
HINT: INDEX(表名/别名索引名)
做个试验:order by后列顺序和索引列顺序不一致则会走 indexfast full scan
create table test as select * from dba_objects;
create index idx on test(owner,object_id);
selectowner,object_id from test where owner is not null and object_id is not nullorder by object_id,owner;
order by 选项indexfull scan是不是没有sort order by ??
分页语句就会用这种方法优化
8.7 indexfast full scan
INDEX FAST FULL SCAN 索引快速全扫描。多块读。当SQL要查询的数据能够完全从索引中获得,那么Oracle就不会走全表扫描了,就会走索引快速全扫描。索引快速全扫描类似全表扫描,它可以多块读,并且可以并行扫描。
等待事件:db filescattered read
HINT:INDEX_FFS(表名/别名索引名)
INDEX FAST FULL SCAN 与 TABLE ACCESS FULL一模一样的
提问:什么情况下走indexfast full scan??
这个时候是不是把索引当表用了??当表用的好处是不是扫描的体积小??是不是减少了I/O
8.8 indexrange scan descending
INDEX RANGE SCAN DESCENDING 索引降序范围扫描。单块读索引扫描默认是升序扫描,当有order by desc这种需求的时候,可能会进行索引降序范围扫描,这种情况多出现在于分页语句上。后面的案例有分页语句的优化。
等待事件:db filesquential read
HINT:INDEX_DESC(表名/别名索引名)
8.9 indexfull scan(min/max)
INDEX FULL SCAN (MIN/MAX) 索引最小/最大值扫描。单块读通常发生在 select
max(xxx) 或者select min(xxx)并且xxx列上有索引。
等待事件:db filesequential read我们几乎观察不到,因为只需读取索引高度相同的indexblock数。
HINT 无需指定,有索引会自动走INDEXFULL SCAN(MIN/MAX)
create index idd on test(object_id);
select max(object_id) from test;
select max(object_id),min(object_id) from test where object_idis not null;
是不是要进行indexfast full scan??是不是要扫描所有的indexblock??
是不是只需要访问索引的最左边或者最右边??
访问索引最左边只需要扫描索引高度这么多个块同理最右边也一样
一般来说索引高度是3那么逻辑读一般是6个
如果不改SQL
是不是要对索引的块都要扫描随着索引的块越多逻辑读越大
8.10mat_view rewrite access full
MAT_VIEW REWRITE ACCESS FULL 物化视图全表扫描。多块读当SQL查询能够直接从物化视图获得结果就会走物化视图查询。
等待事件:同全表扫描
HINT:无。通过ALTERSYSTEM/SESSION SET QUERY_REWRITE_ENABLED = TRUE/FALSE;控制
物化视图就当成是表不要乱建或者查询重写不要乱用
通过ALTERSYSTEM/SESSION SET QUERY_REWRITE_ENABLED=FALSE;将查询重写关掉就不会走物化视图了
为了优化A这个SQL创建了一个物化视图 A现在跑的快了物化视图会影响其他SQL
如SQL B引用了这个物化视图反而跑的更慢了因为B上走索引很快但走了物化视图物化视图上没建立索引
TABLE ACCESS FULL 全表扫描,多块读,等待事件:db file scattered read
如果是并行全表扫描,等待事件:direct path read
11g 有个新特征,在进行全表扫描的时候也会产生direct path read
在OLTP环境中要通过 10949event禁止该新特征
在OLAP环境中可以不用禁止
如果表上面有大量的行迁链接,会是单块读等待事件表现为db filesequential read
如果表上面发生了一个大事物,全表扫描会从UNDO读取前镜像,也会是单块读
HINT: FULL(表名/别名)
提问:假设test表有10GB的数据如果没有索引是不是走全表扫描??
select id from test where owner='SYS';
全表扫描是只扫描id和 owner列还是全扫??是不是
10GB的数据全部扫一遍??
高水位下的都扫对吧??这个时候可以看是不是碎片太多了??是不是经常DML碎片就多??
如果是并行全表扫描,等待事件:direct path read
8.2 rowidscan
ROWID SCAN 根据ROWID取得数据都是单块读
TABLEACCESS BY USER ROWID 直接用ROWID取得数据比如 whererowid='xxxxxx'
TABLEACCESS BY INDEX ROWID 通过索引的ROWID获得数据
提问:为什么通过ROWID回表是单块读??
ROWID是不是一条数据为了读一条数据读多个块合理吗??一个ROWID对应一个块
当然一个ROWID可能对应多个块行迁移
8.3 indexunique scan
INDEX UNIQUE SCAN 索引唯一扫描。单块读只可能发生在unique index/primary key等值查找
等待事件:db filesequential read但是你几乎看不到,因为只读一条数据
HINT 无需指定,有索引会自动走INDEXUNIQUE SCAN
OLAP这个很少见数据仓库不要主键一般不要建索引不然插入数据很慢
8.4 indexrange scan
INDEX RANGE SCAN 索引范围扫描。单块读 发生在对uniqueindex/primary key进行范围查找,对non-uniqueindex进行等值查找,范围查找
等待事件:db filesequential read如果你监控某个SQL出现大量该等待事件,有可能执行计划就有问题
HINT: INDEX(表名/别名索引名)
提问:索引唯一等值扫描需要几个I/O??
索引高度+1 如果存在行迁移则再+1
提问:非唯一索引等值扫描走什么访问路径??
不能判断是返回一条还是多条所以要走indexrange scan
节点的指针叫DBA(datablock address)
提问:为什么索引范围扫描是单块读??
索引是不是有root、branch、leafblock
leaf block之间是不是双向链表??在物理上是连续的吗??索引分裂就不连续了
有insert、update、delete
既然物理上存储不是连续的你能多块读吗??
提问:为什么indexfast full scan有能进行多块读??
索引也有段段由区组成 extent的数据块是不是连续的??
index fast full scan是根据extent来读的 这个时候肯定是多块读
只要通过双向链表扫描都是单块读
索引扫描中只有indexfast full scan才是多块读
是不是你们遇到过很多菜鸟拿到问题就说靠你这个都不走索引肯定慢啊
是不是有时候走索引反而更慢??是不是I/O扫描次数就多了??
SQL优化的核心思想是什么??较少物理I/O其次减少逻辑I/O
8.5 indexskip scan
exadata可以只扫描某个列smart scan
INDEX SKIP SCAN 索引跳跃扫描。单块读只可能发生在组合索引上,引导列(组合索引第一列)没有包含在where条件中,并且引导列基数很低。INDEXSKIP
SCAN一般来说只会返回少量数据,如果返回大量数据,说明该执行计划可能有问题,也就是说索引建立不对。
等待事件:db filesequential read
HINT: INDEX_SS(表名/别名索引名)
发生索引跳跃扫描的条件有哪些??
1. 必须是组合索引
2. 引导列基数很低
3. where条件中没有引导列
提问:为什么这里有个skip
关键字??
因为where条件里面没有引导列但还要去扫描索引
提问:如果where条件里有引导列那走什么??
index range scan 引导列出现在where条件中那么它怎么跳??肯定跳不了的
如果引导列基数很高可能就不会走indexskip scan了
提问:当执行计划中有indexskip scan还能优化吗??
直接建立一个索引不就完了干嘛非要扫描这个破索引呢??
select * from test where id=xx and tablespace=xx;
create index idx on test(owner,id,tablespace);
这个时候是不是可能走indexskip scan??
我直接创建这样的索引走范围扫描不就完了??
create index idx1 on test(id,tablespace);
8.6 indexfull scan
INDEX FULL SCAN 索引全扫描。单块读。它扫描的结果是有序的,因为索引是有序的。它通常发生在
下面几种情况(注意:即使SQL满足以下情况不一定会走索引全扫描)
1.SQL语句有order by选项,并且order by的列都包含在索引中,并且order
by后列顺序必须和索引列顺序一致。
2. 在进行SORTMERGE JOIN的时候,如果要查询的列通过索引就能获得,那就不必进行全表扫描了,另外也避免了排序,因为INDEXFULL
SCAN返回的结果已经排序。
3. 当查询中有GROUP BY,并且GROUP BY的列包含在索引中。
等待事件:db file sequential read
HINT: INDEX(表名/别名索引名)
做个试验:order by后列顺序和索引列顺序不一致则会走 indexfast full scan
create table test as select * from dba_objects;
create index idx on test(owner,object_id);
selectowner,object_id from test where owner is not null and object_id is not nullorder by object_id,owner;
order by 选项indexfull scan是不是没有sort order by ??
分页语句就会用这种方法优化
8.7 indexfast full scan
INDEX FAST FULL SCAN 索引快速全扫描。多块读。当SQL要查询的数据能够完全从索引中获得,那么Oracle就不会走全表扫描了,就会走索引快速全扫描。索引快速全扫描类似全表扫描,它可以多块读,并且可以并行扫描。
等待事件:db filescattered read
HINT:INDEX_FFS(表名/别名索引名)
INDEX FAST FULL SCAN 与 TABLE ACCESS FULL一模一样的
提问:什么情况下走indexfast full scan??
这个时候是不是把索引当表用了??当表用的好处是不是扫描的体积小??是不是减少了I/O
8.8 indexrange scan descending
INDEX RANGE SCAN DESCENDING 索引降序范围扫描。单块读索引扫描默认是升序扫描,当有order by desc这种需求的时候,可能会进行索引降序范围扫描,这种情况多出现在于分页语句上。后面的案例有分页语句的优化。
等待事件:db filesquential read
HINT:INDEX_DESC(表名/别名索引名)
8.9 indexfull scan(min/max)
INDEX FULL SCAN (MIN/MAX) 索引最小/最大值扫描。单块读通常发生在 select
max(xxx) 或者select min(xxx)并且xxx列上有索引。
等待事件:db filesequential read我们几乎观察不到,因为只需读取索引高度相同的indexblock数。
HINT 无需指定,有索引会自动走INDEXFULL SCAN(MIN/MAX)
create index idd on test(object_id);
select max(object_id) from test;
select max(object_id),min(object_id) from test where object_idis not null;
是不是要进行indexfast full scan??是不是要扫描所有的indexblock??
是不是只需要访问索引的最左边或者最右边??
访问索引最左边只需要扫描索引高度这么多个块同理最右边也一样
一般来说索引高度是3那么逻辑读一般是6个
如果不改SQL
是不是要对索引的块都要扫描随着索引的块越多逻辑读越大
8.10mat_view rewrite access full
MAT_VIEW REWRITE ACCESS FULL 物化视图全表扫描。多块读当SQL查询能够直接从物化视图获得结果就会走物化视图查询。
等待事件:同全表扫描
HINT:无。通过ALTERSYSTEM/SESSION SET QUERY_REWRITE_ENABLED = TRUE/FALSE;控制
物化视图就当成是表不要乱建或者查询重写不要乱用
通过ALTERSYSTEM/SESSION SET QUERY_REWRITE_ENABLED=FALSE;将查询重写关掉就不会走物化视图了
为了优化A这个SQL创建了一个物化视图 A现在跑的快了物化视图会影响其他SQL
如SQL B引用了这个物化视图反而跑的更慢了因为B上走索引很快但走了物化视图物化视图上没建立索引
相关文章推荐
- 7 访问路径概述--优化主题系列
- 28 分析函数优化自连接,减少表访问次数 --优化主题系列
- 每天学习一算法系列(6) (输入一个整数和一棵二元树,从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径,打印出和与输入整数相等的所有路径)
- 索引、物化视图-oracle 性能调优之 数据访问路径优化-by小雨
- \t\tSEO相关:关键词优化详细介绍 ( 优化 网站 访问 )
- 4 聚簇因子--优化主题系列
- Memcache(MC)系列(一)Memcache介绍、使用、存储、算法、优化
- 14 外连接(hash join outer)--优化主题系列
- hexo干货系列:(三)hexo的Jacman主题优化
- paper 5:支持向量机系列二: Support Vector —— 介绍支持向量机目标函数的 dual 优化推导,并得出“支持向量”的概念。
- 每天学习一算法系列(6) (输入一个整数和一棵二元树,从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径,打印出和与输入整数相等的所有路径)
- TI C6000系列DSP的流水线介绍和软件流水优化
- SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)
- 22 谓词推入(pushing predicate) --优化主题系列
- 【Android学习笔记系列】BaseAdapter适配器的介绍、使用及优化(详细)
- 11 哈希连接(HASH JOIN)--优化主题系列
- 27 分页语句优化--优化主题系列
- TI C6000系列DSP的流水线介绍和软件流水优化
- 15 半连接(semi-join)--优化主题系列
- 18 索引扫描成本计算--优化主题系列