【Oracle】11g direct path read介绍:10949 event、_small_table_threshold与_serial_direct_read
2018-01-02 11:47
465 查看
转自刘相兵老师的博文:http://www.askmaclean.com/archives/11g-direct-path-read-10949-_small_table_threshold-_serial_direct_read.html
在11g之前串行的扫描大表默认总是先将数据读取到Oracle高速缓冲中,其等待事件常为db file scattered read。 从11g开始Oracle通过内部算法来决定串行扫描大表是通过直接路径读direct path read,还是先读入到buffer cache中,此算法依据表的大小评估。 _small_table_threshold 隐藏参数指定了 ORACLE中大表的阀值,其单位为block,即大于_small_table_threshold 所指定的块数的表被视作大表,否之视为”small table”。 对于大表”large table”,SQL执行层认为存在直接路径读取的意义(direct path read)。 对于小表,将它缓存在buffer cache中的收益更大,所以直接路径读取不具有意义。_small_table_threshold 隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。 direct path read的优势: 1. 减少了对闩(latch)的使用,避免可能的闩争用 2.物理IO的大小不再取决于buffer_cache中所存在的块;试想某个8个块的extent中1,3,5,7号块在高速缓存中,而2,4,6,8块没有被缓存,传统的方式在读取该extent时将会是对2,4,6,8块进行4次db file sequentialread,其效率往往要比单次读取这个区间的所有8个块还要低得多,Oracle为了避免这种情况总是尽可能的不缓存大表的块(读入后总是放在队列最冷的一端);而direct path read则可以完全避免这类问题,尽可能地单次读入更多的物理块。 当然直接路径读取也会引入一些缺点: 1.即便在buffer cache足够大到可以放下整个大表的情况下,direct path read无法从高速缓冲受益,每次扫描大表均需重复等量的直接路径物理读取IO2.在直接路径读取某段前需要对该对象进行一次段级的检查点(A segment checkpoint).3.可能导致重复的延迟块清除操作 该11g自动判断direct path read的特性适用场景: 1. 对大表不频繁地串行全表扫描的场景2. Db Cache Size高速缓冲大小远小于表的大小的场景 不推荐在以下场景中开启该11g自动判断direct path read特性: 1. 从运行稳定的老版本(9i、10g)升级到11g的数据库2. 对大表频繁地串行全表扫描的场景 SQL> select * from v$version; BANNER——————————————————————————–Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – 64bit ProductionPL/SQL Release 11.2.0.3.0 – ProductionCORE 11.2.0.3.0 ProductionTNS for Linux: Version 11.2.0.3.0 – ProductionNLSRTL Version 11.2.0.3.0 – Production col name for a30col value for a20col DESCRIB for a60set linesize 140 pagesize 1400 SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describFROM SYS.x$ksppi x, SYS.x$ksppcv yWHERE x.inst_id = USERENV (‘Instance’)AND y.inst_id = USERENV (‘Instance’)AND x.indx = y.indxAND (x.ksppinm =’_small_table_threshold’ or x.ksppinm=’_serial_direct_read’); NAME VALUE DESCRIB—————————— ——————– ————————————————————_small_table_threshold 1143 lower threshold level of table size for direct reads_serial_direct_read auto enable direct read in serial 其中_small_table_threshold 隐藏参数指定了 ORACLE中大表的阀值,其单位为block,即大于_small_table_threshold 所指定的块数的表被视作大表,否之视为”small table”。 对于大表”large table”,SQL执行层认为存在直接路径读取的意义(direct path read)。 对于小表,将它缓存在buffer cache中的收益更大,所以直接路径读取不具有意义。 _small_table_threshold 隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。 SQL> alter system set db_cache_size=1024M scope=spfile; System altered. RESTART INSTANCE: SQL> col name for a30SQL> col value for a20SQL> col DESCRIB for a60SQL> set linesize 140 pagesize 1400SQL>SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ2 FROM SYS.x$ksppi x, SYS.x$ksppcv y3 WHERE x.inst_id = USERENV (‘Instance’)4 AND y.inst_id = USERENV (‘Instance’)5 AND x.indx = y.indx6 AND (x.ksppinm =’_small_table_threshold’ or x.ksppinm=’_serial_direct_read’); NAME VALUE DESCRIB—————————— ——————– ————————————————————_small_table_threshold 2522 lower threshold level of table size for direct reads_serial_direct_read auto enable direct read in serial 2522 block = 2522 * 8k = = 19.7 M 约等于 1024 * 2% SQL> create table tmac (t1 char(2000)) pctfree 99 pctused 1 tablespace users; Table created. SQL> insert into tmac select ‘MACLEAN’ from dual connect by level <=2530; 2530 rows created. SQL> commit; Commit complete. SQL> exec dbms_stats.gather_table_stats(‘SYS’,’TMAC’); PL/SQL procedure successfully completed. SQL> select blocks from dba_tables where table_name=’TMAC’; BLOCKS———-2638SQL> alter system flush buffer_cache; SQL> select count(*) from tmac; COUNT(*)———-2530 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 2859135 physical reads 2763135 physical reads direct 2576135 cleanouts only – consistent read gets 0 physical reads direct 增加说明上面的查询使用了direct path read SQL> alter session set “_serial_direct_read”=never; Session altered. SQL> select count(*) from tmac; COUNT(*)———-2530 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 5497135 physical reads 5339135 physical reads direct 2576135 cleanouts only – consistent read gets 0SQL> select count(*) from tmac; COUNT(*)———-2530 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 8135135 physical reads 5339135 physical reads direct 2576135 cleanouts only – consistent read gets 0 physical reads direct 不再增加说明以上2次查询未使用direct path read隐藏参数”_serial_direct_read” 指定了是否启用串行全表扫描下的直接路径读取(direct path read),其默认值为AUTO,设置为NEVER时禁用11g自动direct path read的特性 SQL> alter session set “_serial_direct_read”=auto; Session altered. 还原session级别的_serial_direct_read 参数 SQL> delete tmac where rownum<2000; 1999 rows deleted. SQL> commit; Commit complete. SQL> alter table tmac move tablespace users pctfree 10 pctused 90; Table altered. SQL> exec dbms_stats.gather_table_stats(‘SYS’,’TMAC’); PL/SQL procedure successfully completed. SQL> select blocks from dba_tables where table_name=’TMAC’; BLOCKS———-189 将TMAC表缩小到 _small_table_threshold以下 SQL> alter system flush buffer_cache; System altered. SQL> select count(*) from tmac; COUNT(*)———-531 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 524135 physical reads 349135 physical reads direct 0135 cleanouts only – consistent read gets 1 以上演示证明对于small table(块数小于_small_table_threshold),SQL执行层自动并不决定使用direct path read,而是将之读取到buffer cache中并逻辑读。 结论: 其中_small_table_threshold 隐藏参数指定了 ORACLE中大表的阀值,其单位为block,即大于_small_table_threshold 所指定的块数的表被视作大表,否之视为”small table”。 对于大表”large table”,SQL执行层认为存在直接路径读取的意义(direct path read)。 对于小表,将它缓存在buffer cache中的收益更大,所以直接路径读取不具有意义。 _small_table_threshold 隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。 隐藏参数”_serial_direct_read” 指定了是否启用串行全表扫描下的直接路径读取(direct path read),其默认值为AUTO,设置为NEVER时禁用11g自动direct path read的特性 “As of 11.2.0.2 the legal settings aretrue, false, always, auto, and nevertrue is the same effect as alwaysfalse is the same effect as autoDefault value is “auto”Setting event 10949 or event 10354 may also have the side effect of making oracle behave as if _serial_direct_read = never” 该参数可以动态在实例或会话级别修改,而无需重启实例。 类似的10949 EVENT事件也可以起到类似的作用。 设置event 10949可以避免采用直接路径读取方式,该事件可以在线设置,但对现有session可能不会生效: 在实例级别设置: ALTER SYSTEM SET EVENTS ‘10949 TRACE NAME CONTEXT FOREVER’; 设置到SPFILE中: alter system set event=’10949 TRACE NAME CONTEXT FOREVER’ scope=spfile; 在session级别设置: ALTER SESSION SET EVENTS ‘10949 TRACE NAME CONTEXT FOREVER’;
在11g之前串行的扫描大表默认总是先将数据读取到Oracle高速缓冲中,其等待事件常为db file scattered read。 从11g开始Oracle通过内部算法来决定串行扫描大表是通过直接路径读direct path read,还是先读入到buffer cache中,此算法依据表的大小评估。 _small_table_threshold 隐藏参数指定了 ORACLE中大表的阀值,其单位为block,即大于_small_table_threshold 所指定的块数的表被视作大表,否之视为”small table”。 对于大表”large table”,SQL执行层认为存在直接路径读取的意义(direct path read)。 对于小表,将它缓存在buffer cache中的收益更大,所以直接路径读取不具有意义。_small_table_threshold 隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。 direct path read的优势: 1. 减少了对闩(latch)的使用,避免可能的闩争用 2.物理IO的大小不再取决于buffer_cache中所存在的块;试想某个8个块的extent中1,3,5,7号块在高速缓存中,而2,4,6,8块没有被缓存,传统的方式在读取该extent时将会是对2,4,6,8块进行4次db file sequentialread,其效率往往要比单次读取这个区间的所有8个块还要低得多,Oracle为了避免这种情况总是尽可能的不缓存大表的块(读入后总是放在队列最冷的一端);而direct path read则可以完全避免这类问题,尽可能地单次读入更多的物理块。 当然直接路径读取也会引入一些缺点: 1.即便在buffer cache足够大到可以放下整个大表的情况下,direct path read无法从高速缓冲受益,每次扫描大表均需重复等量的直接路径物理读取IO2.在直接路径读取某段前需要对该对象进行一次段级的检查点(A segment checkpoint).3.可能导致重复的延迟块清除操作 该11g自动判断direct path read的特性适用场景: 1. 对大表不频繁地串行全表扫描的场景2. Db Cache Size高速缓冲大小远小于表的大小的场景 不推荐在以下场景中开启该11g自动判断direct path read特性: 1. 从运行稳定的老版本(9i、10g)升级到11g的数据库2. 对大表频繁地串行全表扫描的场景 SQL> select * from v$version; BANNER——————————————————————————–Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – 64bit ProductionPL/SQL Release 11.2.0.3.0 – ProductionCORE 11.2.0.3.0 ProductionTNS for Linux: Version 11.2.0.3.0 – ProductionNLSRTL Version 11.2.0.3.0 – Production col name for a30col value for a20col DESCRIB for a60set linesize 140 pagesize 1400 SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describFROM SYS.x$ksppi x, SYS.x$ksppcv yWHERE x.inst_id = USERENV (‘Instance’)AND y.inst_id = USERENV (‘Instance’)AND x.indx = y.indxAND (x.ksppinm =’_small_table_threshold’ or x.ksppinm=’_serial_direct_read’); NAME VALUE DESCRIB—————————— ——————– ————————————————————_small_table_threshold 1143 lower threshold level of table size for direct reads_serial_direct_read auto enable direct read in serial 其中_small_table_threshold 隐藏参数指定了 ORACLE中大表的阀值,其单位为block,即大于_small_table_threshold 所指定的块数的表被视作大表,否之视为”small table”。 对于大表”large table”,SQL执行层认为存在直接路径读取的意义(direct path read)。 对于小表,将它缓存在buffer cache中的收益更大,所以直接路径读取不具有意义。 _small_table_threshold 隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。 SQL> alter system set db_cache_size=1024M scope=spfile; System altered. RESTART INSTANCE: SQL> col name for a30SQL> col value for a20SQL> col DESCRIB for a60SQL> set linesize 140 pagesize 1400SQL>SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ2 FROM SYS.x$ksppi x, SYS.x$ksppcv y3 WHERE x.inst_id = USERENV (‘Instance’)4 AND y.inst_id = USERENV (‘Instance’)5 AND x.indx = y.indx6 AND (x.ksppinm =’_small_table_threshold’ or x.ksppinm=’_serial_direct_read’); NAME VALUE DESCRIB—————————— ——————– ————————————————————_small_table_threshold 2522 lower threshold level of table size for direct reads_serial_direct_read auto enable direct read in serial 2522 block = 2522 * 8k = = 19.7 M 约等于 1024 * 2% SQL> create table tmac (t1 char(2000)) pctfree 99 pctused 1 tablespace users; Table created. SQL> insert into tmac select ‘MACLEAN’ from dual connect by level <=2530; 2530 rows created. SQL> commit; Commit complete. SQL> exec dbms_stats.gather_table_stats(‘SYS’,’TMAC’); PL/SQL procedure successfully completed. SQL> select blocks from dba_tables where table_name=’TMAC’; BLOCKS———-2638SQL> alter system flush buffer_cache; SQL> select count(*) from tmac; COUNT(*)———-2530 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 2859135 physical reads 2763135 physical reads direct 2576135 cleanouts only – consistent read gets 0 physical reads direct 增加说明上面的查询使用了direct path read SQL> alter session set “_serial_direct_read”=never; Session altered. SQL> select count(*) from tmac; COUNT(*)———-2530 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 5497135 physical reads 5339135 physical reads direct 2576135 cleanouts only – consistent read gets 0SQL> select count(*) from tmac; COUNT(*)———-2530 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 8135135 physical reads 5339135 physical reads direct 2576135 cleanouts only – consistent read gets 0 physical reads direct 不再增加说明以上2次查询未使用direct path read隐藏参数”_serial_direct_read” 指定了是否启用串行全表扫描下的直接路径读取(direct path read),其默认值为AUTO,设置为NEVER时禁用11g自动direct path read的特性 SQL> alter session set “_serial_direct_read”=auto; Session altered. 还原session级别的_serial_direct_read 参数 SQL> delete tmac where rownum<2000; 1999 rows deleted. SQL> commit; Commit complete. SQL> alter table tmac move tablespace users pctfree 10 pctused 90; Table altered. SQL> exec dbms_stats.gather_table_stats(‘SYS’,’TMAC’); PL/SQL procedure successfully completed. SQL> select blocks from dba_tables where table_name=’TMAC’; BLOCKS———-189 将TMAC表缩小到 _small_table_threshold以下 SQL> alter system flush buffer_cache; System altered. SQL> select count(*) from tmac; COUNT(*)———-531 SQL> select vm.sid, vs.name, vm.value2 from v$mystat vm, v$sysstat vs3 where vm.statistic# = vs.statistic#4 and vs.name in (‘cleanouts only – consistent read gets’,5 ‘session logical reads’,6 ‘physical reads’,7 ‘physical reads direct’); SID NAME VALUE———- —————————————————————- ———-135 session logical reads 524135 physical reads 349135 physical reads direct 0135 cleanouts only – consistent read gets 1 以上演示证明对于small table(块数小于_small_table_threshold),SQL执行层自动并不决定使用direct path read,而是将之读取到buffer cache中并逻辑读。 结论: 其中_small_table_threshold 隐藏参数指定了 ORACLE中大表的阀值,其单位为block,即大于_small_table_threshold 所指定的块数的表被视作大表,否之视为”small table”。 对于大表”large table”,SQL执行层认为存在直接路径读取的意义(direct path read)。 对于小表,将它缓存在buffer cache中的收益更大,所以直接路径读取不具有意义。 _small_table_threshold 隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。 隐藏参数”_serial_direct_read” 指定了是否启用串行全表扫描下的直接路径读取(direct path read),其默认值为AUTO,设置为NEVER时禁用11g自动direct path read的特性 “As of 11.2.0.2 the legal settings aretrue, false, always, auto, and nevertrue is the same effect as alwaysfalse is the same effect as autoDefault value is “auto”Setting event 10949 or event 10354 may also have the side effect of making oracle behave as if _serial_direct_read = never” 该参数可以动态在实例或会话级别修改,而无需重启实例。 类似的10949 EVENT事件也可以起到类似的作用。 设置event 10949可以避免采用直接路径读取方式,该事件可以在线设置,但对现有session可能不会生效: 在实例级别设置: ALTER SYSTEM SET EVENTS ‘10949 TRACE NAME CONTEXT FOREVER’; 设置到SPFILE中: alter system set event=’10949 TRACE NAME CONTEXT FOREVER’ scope=spfile; 在session级别设置: ALTER SESSION SET EVENTS ‘10949 TRACE NAME CONTEXT FOREVER’;
相关文章推荐
- 11g direct path read介绍:10949 event、_small_table_threshold与_serial_direct_read
- 11g direct path read介绍:10949 event、_small_table_threshold与_serial_direct_read
- ORACLE _small_table_threshold与event 10949与direct path read测试 推荐
- Oracle 11g direct path read 等待事件的理解
- oracle wait event: Direct Path Read Temp
- 【转自Oracle ACE-盖国强】Oracle 11g全表扫描以Direct Path Read方式执行
- Oracle 11g direct path read 等待事件的理解
- Oracle 11g新特性direct path read引发的系统停运故障诊断处理2
- Oracle 11g全表扫描以Direct Path Read方式执行
- oracle 11g direct path read new feature
- Oracle 11g全表扫描以Direct Path Read方式执行
- Oracle 11g全表扫描以Direct Path Read方式执行
- Oracle 11g新特性direct path read引发的系统停运故障诊断处理
- Oracle 11g全表扫描以Direct Path Read方式执行
- Oracle 11g全表扫描以Direct Path Read方式执行
- Oracle 参数之_small_table_threshold
- oracle等待事件-direct path read/write
- Oracle 11g新特性之--只读表(read only table)
- Oracle 11g 新特性 -- 只读表(read-only table)
- 11g中,HWM导致表大小超过_small_table_threshold,以致SQL物理读高的调优