访问路径(ACCESSPATH)
前面提到过执行计划中的访问路径,访问路径指的是ORACLE通过哪种方式去获取数据,比如通过全部扫描,索引扫描,或者通过ROWID获取数据。下面列举一些常见的访问路径:
(注意:我没有完全列举所有的访问路径,只列举了工作中99%见到的)
如tableaccess full、rowidscan、indexunique scan、indexrange scan、indexskip scan、indexfull scan、indexfast full scan、indexrange scan descending、indexfull scan(min/max)、mat_viewrewrite access full等,并将一步步道来。
首先,介绍访问路径前,先对dbfile sequential read进行介绍。
提问:什么情况下发生dbfile sequential read??
1. 索引扫描,除了INDEXFAST FULL SCAN
2. 行迁移,行连接
3. 读undo块
4. rowid回表
5. 特殊情况,比如边界的block,buffercache不连续,段头
如果查询的数据都在buffercache中会发生这个等待事件吗??
不会的发生这个等待事件的前提是从磁盘把数据读入到buffercache中产生物理I/O
全表扫描有没有可能发生单块读??可以前提是行迁移行链接
假设 OLAP环境中一个表10GB数据大概几分钟全表扫描但跑了很久跑不出来
监控等待事件发现是单块读最后发现是行迁移导致
监控等待事件:
select (sysdate - a.logon_time) * 24 * 60 minutes,
a.username,
a.BLOCKING_INSTANCE,
a.BLOCKING_SESSION,
a.program,
a.machine,
a.osuser,
a.status,
a.sid,
a.serial#,
a.event,
a.p1,
a.p2,
a.p3,
a.sql_id,
a.sql_child_number,
b.sql_text
from v$session a, v$sql b
where a.sql_address = b.address
and a.sql_hash_value = b.hash_value
and a.sql_child_number = b.child_number
and a.username like '%USERNAME%'
order by 1 desc;
select (sysdate - logon_time) * 24 * 60 minutes,
username,
machine,
program,
action,
status,
inst_id,
sid,
serial#,
event,
p1,
p2,
p3,
row_wait_obj# obj#,
row_wait_file# file#,
row_wait_block# block#,
sql_id,
sql_child_number
from gv$session
where sql_id = 'XXX';
obj# 表示DBA_OBJECTS里面的OBJECT_ID
file# 表示它等待的文件号
block# 表示块号
通常我们只需要获得OBJECT_ID就行了
获得了OBJECT_ID通过查询DBA_objects就能看到等待的对象是索引还是表
ROW_WAIT_OBJ# ---这个是对象号
直接关联DBA_OBJECTS
通过这个字段就能查到单块读发生在哪个对象上面
一行数据不是存储在同一个数据块中
既然在不同的物理磁盘上面能多块读吗??
有没有遇到过死事务恢复的???
假如一个10GB的表要删除其中的5GB数据但没commit此时断电或被KILL掉了活DB崩溃了
是不是ORACLE要对此事务进行自动回滚这样的死事务自动回滚慢不??
从UNDO里面读数据是单块读
假设多块读是128 块大小是8KB 那么5GB的数据要读多少次I/O??
select 5*1024*1024/128/8 from dual; --5120
删除时是多块读但回滚时是单块读是不是比删除时速度降低了128倍??
假设之前5GB数据删除时10分钟搞定那么恢复是不是需要10*128分钟??
找到等待事件,怎么发现行连接是通过row_wait_obj#查看
你们是不是可以去监控某个session跑的状态
各种统计值通过视图sesstat看到行迁移的值特别大