oracle CBO优化器何时会选择全表扫描

全表扫描将读取高水位线(HWM)之下的所有数据块从数据文件读到缓冲区,然后读取每项行数据,看是否满足WHERE子句过滤条件。
当Oracle执行全表扫描时会按顺序读取每个块且只读一次,如果能够一次读取多个块,可以有效的提高效率,
初始化参数DB_FILE_MULTIBLOCK_READ_COUNT用来设置在一次I/O中可以读取多少个数据块。


通常我们认为应该避免全表扫描,但是在检索大量数据时全表扫描优于索引扫描,这正是因为全表扫描可以在一次I/O中读却多个块,从而减少了I/O的次数。在使用全表扫描的同时也可以使用并行来提高扫描的速度。

CBO优化器何时会选择全表扫描:
1) 无合适的索引。
2) 检索表中绝大多数的数据。  
3) 表非常小。


SQL> create table d as select * from scott.emp where deptno=10;
SQL> select * from d;
EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
 7782 CLARK      MANAGER    7839 1981/6/9      2450.00               10
 7839 KING       PRESIDENT       1981/11/17    5000.00               10
 7934 MILLER     CLERK      7782 1982/1/23     1300.00               10

SQL>create index empno_index on d (empno);
SQL>select * from d where empno=7782;  


Execution Plan
----------------------------------------------------------
Plan hash value: 3387653791

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    87 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| D    |     1 |    87 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("EMPNO"=7782)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          9  recursive calls
          0  db block gets
         10  consistent gets
          0  physical reads
          0  redo size
        864  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

因为表中的块小于参数DB_FILE_MULTIBLOCK_READ_COUNT设置的值,只需一次I/O

4) 高并行度。             
如果在表级设置了较高的并行度,通常会使CBO选择全表扫描。
通常建议在语句级用HINTS来实现并行,如/*+full(table_name) parallel(table_name degree)*/。
5) 太旧的统计数据。如果表没有进行过分析或很久没有再次分析,CBO可能会错误的认为表含有及少的数据块。------- 必要时对表手动做统计信息
6) 在语句中嵌入了全表扫描的HINTS。  ----- 指定表的执行计划路径

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值