本文将回答:什么是动态抽样?动态抽样有啥作用?以及不同级别的动态抽样的意思?
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
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)单独列,高低值,唯一值数量,直方图(可能)