动态采样(Dynamic Sampling)是在Oracle 9i Release 2中开始引入的一个技术,引入它的目的是为了应对数据库对象没有分析(统计信息缺失)的情况下,优化器生成更好的执行计划。简单的说,在数据库段(表、索引、分区)对象没有分析的情况下,为了使CBO优化器得到足够多的信息以保证优化器做出正确执行计划而发明的一种技术。它会分析一定数量段对象上的数据块获取CBO需要的统计信息。动态采样技术仅仅是统计信息的一种补充,它不能完全替代统计信息分析。
注意:动态采样在Oracle 11g之前称为 Dynamic Sampling, ORACLE 12c之后改名为Dynamic Statistic.
Oracle11G R2 默认的采样级别:
SQL> show parameter optimizer_dynamic_sampling
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 2
SQL> show parameter Dynamic Statistic
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 2
动态采样的级别有11个级别:请自行查看官方文档
#PFGRF30101
动态采样实验:
1、创建测试表test
SQL> create table test as select * from dba_objects;
Table created.
SQL> select count(1) from test;
COUNT(1)
----------
86259
2、不使用动态采样,查看执行计划
SQL> set autotrace traceonly explain;
SQL> select /*+ dynamic_sampling(test 0) */ * from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100K| 19M| 336 (1)| 00:00:05 |
| 1 | TABLE ACCESS FULL| TEST | 100K| 19M| 336 (1)| 00:00:05 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
从上面可以看出,次数优化器估计表test的行数显示为100K,我们再看下面使用动态采样的执行计划,优化器会估算多少行:
3、使用动态采样,查看执行计划(下面是直接查询的,因为在11G 是默认启用动态采样的)
SQL> select * from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 72258 | 14M| 336 (1)| 00:00:05 |
| 1 | TABLE ACCESS FULL| TEST | 72258 | 14M| 336 (1)| 00:00:05 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
如果启用动态采样(默认情况下,动态采样级别为2),优化器根据动态采样得到一些数据信息猜测、估计表TEST的记录行数为86259,已经接近实际记录行数72258了。比不做动态采样分析要好很多了。
如果我们将动态采样的级别提高为3,如下所示,发现优化器根据动态采样得到的信息比默认(默认情况下,动态采样级别为2)情况获得的信息更准确。优化器估计表TEST的行数为92364,比72258又接近实际情况一步了。
SQL> select /*+ dynamic_sampling(test 3) */ * from test;
Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 92364 | 18M| 336 (1)| 00:00:05 |
| 1 | TABLE ACCESS FULL| TEST | 92364 | 18M| 336 (1)| 00:00:05 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)