关于动态抽样(DynamicSampling)(一)

2015-01-27 22:37:29 · 作者: · 浏览: 68

本文将回答:什么是动态抽样?动态抽样有啥作用?以及不同级别的动态抽样的意思?


1、什么是动态采样?
动态抽样从 oracle 9i第2版引入。它使得优化器(CBO)在硬解析期间有能力抽样一个未分析的表
(any table that has been created and loaded but not yet analyzed)的统计(决定表默认统计),并且可以验证优化器的”猜想“。
因其只在查询硬解析期间为优化器动态生成更好的统计,得名动态采样。


动态采样提供11个设置级别。注意:9i中其默认值为1 到了10g默认值为2


2、动态采样如何工作?
有两种使用方式:
△ 设置OPTIMIZER_DYNAMIC_SAMPLING参数,可以再实例和会话级别设置动态采样。
△ 使用DYNAMIC_SAMPLING hint


来看一下不使用动态采样的日子怎么过的
create table t
as
select owner, object_type
from all_objects
/




select count(*) from t;


COUNT(*)
------------------------
68076

code1: 禁用动态采样观察默认基数


set autotrace traceonly explain
SQL> select /*+ dynamic_sampling(t 0) */ * from t;


Execution Plan
------------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16010 | 437K| 55 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T | 16010 | 437K| 55 (0)| 00:00:01 |
--------------------------------------------------------------------------



--注意0级别即为禁用动态采样,环境默认是开启动态采样的


执行计划显示基数:16010远低于上面查询的68076,明显不靠谱。


code2: 更加接近显示的基数
select * from t;


Execution Plan
------------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 77871 | 2129K| 56 (2)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T | 77871 | 2129K| 56 (2)| 00:00:01 |
--------------------------------------------------------------------------


Note
------------------------------------------
- dynamic sampling used for this statement




code3: 被高估的基数
SQL> delete from t;
68076 rows deleted.


SQL> commit;
Commit complete.


SQL> set autotrace traceonly explain
SQL> select /*+ dynamic_sampling(t 0) */ * from t;


Execution Plan
------------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16010 | 437K| 55 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T | 16010 | 437K| 55 (0)| 00:00:01 |
--------------------------------------------------------------------------


SQL> select * from t;


Execution Plan
-----------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 55 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T | 1 | 28 | 5 (0)| 00:00:01 |
--------------------------------------------------------------------------


Note
---------------------------------------
- dynamic sampling used for this statement



3、动态采样何时帮助优化器验证其猜测?
我们知道当使用DBMS_STATS收集了表信息后,优化器会得到以下统计:
1)表,行数,平均行宽等;
2)单独列,高低值,唯一值数量,直方图(可能)