【DB笔试面试631】在Oracle中,什么是动态采样(Dynamic Sampling)?_小麦苗DBA宝典的博客-程序员秘密

640?wx_fmt=gif

题目部分

在Oracle中,什么是动态采样(Dynamic Sampling)?

     

答案部分

对于没有收集统计信息的表,Oracle为了能够得到相对准确的执行计划,会在执行SQL之前对SQL语句涉及到的表做动态采样(Dynamic Sampling,从Oracle 11.2.0.4开始称之为Dynamic Statistic)。

有两种方法可以开启动态采样:

(1)将参数OPTIMIZER_DYNAMIC_SAMPLING的值设为大于或等于1。从Oracle 10g开始,该值默认为2,若设置为0,则禁用动态采样。

(2)使用动态采样的Hint:DYNAMIC_SAMPLING(T LEVEL)。该Hint表示对目标表T强制使用等级为参数level指定值的动态采样。

默认采样数据块数量受隐含参数“_OPTIMIZER_DYN_SMP_BLKS”的控制,其默认值是32,表示动态采样时默认采样数据块数量为32。

 [email protected] > set pagesize 9999
 [email protected] > set line 9999
 [email protected] > col NAME format a40
 [email protected] > col KSPPDESC format a50
 [email protected] > col KSPPSTVL format a20
 [email protected] > SELECT a.INDX,
 7  2         a.KSPPINM NAME,
 8  3         a.KSPPDESC,
 9  4         b.KSPPSTVL 
10  5  FROM   x$ksppi  a,
11  6         x$ksppcv b
12  7  WHERE  a.INDX = b.INDX
13  8  and lower(a.KSPPINM) like  lower('%&parameter%');
14Enter value for parameter: _optimizer_dyn_smp_blks
15old   8: and lower(a.KSPPINM) like  lower('%&parameter%')
16new   8: and lower(a.KSPPINM) like  lower('%_optimizer_dyn_smp_blks%')
17
18      INDX NAME                                     KSPPDESC                                           KSPPSTVL
19---------- ---------------------------------------- -------------------------------------------------- --------------------
20      2082 _optimizer_dyn_smp_blks                  number of blocks for optimizer dynamic sampling    32

下表针对Oracle 11.2.0.4(对Oracle 10g而言,采样的数据块数量有差异,详见官方文档)不同采样级别的差异:

640?wx_fmt=png

采样的数据块越多,得到的分析数据就越接近于真实,但同时伴随着资源消耗也越大。

引入动态采样有如下几方面的作用:

① CBO依赖的是充分的统计信息,但是并不是每个用户都会非常认真、及时地去对每个表做分析。为了保证执行计划都尽可能地准确,Oracle需要使用动态采样技术来帮助CBO获取尽可能多的信息。

② 全局临时表。通常来讲,临时表的数据是不做分析的,但是当一个查询关联到这样的临时表时,CBO要想获得临时表上的统计信息分析数据,就只能依赖于动态采样了。

③ 为了相对准确地估算出当目标SQL语句WHERE条件中出现有关联关系的列时整个WHERE条件的组合可选择率,进而能相对准确地估算出返回结果集的Cardinality。动态采样除了可以在段对象没有分析时,给CBO提供分析数据之外,还可以对不同列之间的相关性做统计。

④ 在Oracle 11gR2开始,Oracle对动态采样进行了增强。在Oracle提供的增强特性中,对于并行或大表的复杂条件,即使表上存在统计信息,Oracle也会开启动态采样的功能,试图来更精准的评估返回结果集的记录数,并且自行定义动态采样的级别,Oracle会忽略OPTIMIZER_DYNAMIC_SAMPLING参数或提示Hint的DYNAMIC_SAMPLING值,而自行决定采样级别,如下所示:

 1SQL>  select /*+ dynamic_sampling (my_table 2) */ * from my_table;
 2
 3Execution Plan
 4----------------------------------------------------------
 5Plan hash value: 3006137970
 6
 7--------------------------------------------------------------------------------------------------------------
 8| Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
 9--------------------------------------------------------------------------------------------------------------
10|   0 | SELECT STATEMENT     |          |  9408K|  1704M|  4000   (2)| 00:00:01 |        |      |            |
11|   1 |  PX COORDINATOR      |          |       |       |            |          |        |      |            |
12|   2 |   PX SEND QC (RANDOM)| :TQ10000 |  9408K|  1704M|  4000   (2)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
13|   3 |    PX BLOCK ITERATOR |          |  9408K|  1704M|  4000   (2)| 00:00:01 |  Q1,00 | PCWC |            |
14|   4 |     TABLE ACCESS FULL| MY_TABLE |  9408K|  1704M|  4000   (2)| 00:00:01 |  Q1,00 | PCWP |            |
15--------------------------------------------------------------------------------------------------------------
16
17Note
18-----
19   - dynamic sampling used for this statement (level=5)

在10053的Trace文件中会看到以下内容:

1Dynamic sampling level auto-adjusted from 2 to 5

可以通过“alter session set "_fix_control"='7452863:OFF';”或关闭表的并行来屏蔽该动态采样的增强特性。

动态采样的一些缺点如下所示:

① 采样的数据块有限,对于海量数据的表,结果难免有偏差。

② 采样会消耗系统资源,特别是OLTP数据库,尤其不推荐使用动态采样。动态采样也需要额外的消耗数据库资源。在OLTP系统中,SQL被反复执行,变量被绑定,硬解析很少,在这样一个环境中,是不宜使用动态采样的。在OLAP或者数据仓库环境下,SQL执行消耗的资源要远远大于SQL解析,那么让解析在消耗多一点资源做一些动态采样分析,从而做出一个最优的执行计划是非常值得的。所以,一般在OLAP或者数据仓库环境中,将动态采样的level设置为3或者4比较好。相反,在OLTP系统下,尽量避免使用动态采样。

③ 存在部分Bug。例如,Bug 17760686,当某个查询涉及到分区表时,动态采样可能会估算出很小甚至是0的结果集。

在执行计划的Note部分若有“dynamic sampling used for this statement (level=2)”,则表示Oracle使用了level为2的动态采样。详细情况参考:Bug 17760686 - Bad Cardinality estimation with dynamic sampling (文档 ID 17760686.8)。

下面给出动态采样的一个示例:

创建表:

[email protected] > create table T_DS_20170601_LHR as select owner,object_type from all_objects;
2Table created.
[email protected] > SELECT COUNT(*) FROM T_DS_20170601_LHR;
4  COUNT(*)
5----------
6     75297

这里创建了一张普通表,没有做分析,在Hint中用0级来限制动态采样,此时CBO唯一可以使用的信息就是表存储在数据字典中的一些信息,如有多少个extent,有多少个block,但是这些信息是不够的。

 [email protected] > set autot traceonly explain
 [email protected] > select /*+dynamic_sampling(t 0) */ * from T_DS_20170601_LHR T;
 3Execution Plan
 4----------------------------------------------------------
 5Plan hash value: 1447218522
 6---------------------------------------------------------------------------------------
 7| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
 8---------------------------------------------------------------------------------------
 9|   0 | SELECT STATEMENT  |                   | 16745 |   457K|    57   (0)| 00:00:01 |
10|   1 |  TABLE ACCESS FULL| T_DS_20170601_LHR | 16745 |   457K|    57   (0)| 00:00:01 |
11---------------------------------------------------------------------------------------

在没有做动态分析的情况下,CBO估计的记录数是16745条,与真实的75297相差甚远。下面用动态分析来查看一下:

 [email protected] > select * from T_DS_20170601_LHR;
 2Execution Plan
 3----------------------------------------------------------
 4Plan hash value: 1447218522
 5---------------------------------------------------------------------------------------
 6| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
 7---------------------------------------------------------------------------------------
 8|   0 | SELECT STATEMENT  |                   | 78053 |  2134K|    58   (2)| 00:00:01 |
 9|   1 |  TABLE ACCESS FULL| T_DS_20170601_LHR | 78053 |  2134K|    58   (2)| 00:00:01 |
10---------------------------------------------------------------------------------------
11Note
12-----
13   - dynamic sampling used for this statement (level=2)

上面的查询结果显示使用了Level 2级的动态采样,CBO 估计的结果是78053与75297很接近。需要注意的是,在没有动态采样的情况下,对于没有分析过的段,CBO也可能错误地将结果判断的程度扩大化,例如:

 [email protected] > delete from T_DS_20170601_LHR;
 275297 rows deleted.
 [email protected] > COMMIT;
 4Commit complete.
 [email protected] > SELECT /*+DYNAMIC_SAMPLING(T 0) */ * FROM T_DS_20170601_LHR T;
 6Execution Plan
 7----------------------------------------------------------
 8Plan hash value: 1447218522
 9---------------------------------------------------------------------------------------
10| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
11---------------------------------------------------------------------------------------
12|   0 | SELECT STATEMENT  |                   | 16745 |   457K|    57   (0)| 00:00:01 |
13|   1 |  TABLE ACCESS FULL| T_DS_20170601_LHR | 16745 |   457K|    57   (0)| 00:00:01 |
14---------------------------------------------------------------------------------------
[email protected] > SELECT * FROM T_DS_20170601_LHR T;
16Execution Plan
17----------------------------------------------------------
18Plan hash value: 1447218522
19---------------------------------------------------------------------------------------
20| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
21---------------------------------------------------------------------------------------
22|   0 | SELECT STATEMENT  |                   |     1 |    28 |    57   (0)| 00:00:01 |
23|   1 |  TABLE ACCESS FULL| T_DS_20170601_LHR |     1 |    28 |    57   (0)| 00:00:01 |
24---------------------------------------------------------------------------------------
25Note
26-----
27   - dynamic sampling used for this statement (level=2)

在没有采用动态分析的情况下,CBO对T_DS_20170601_LHR表估计的还是16745行记录,但是用动态分析就显示1条记录。而表中的数据在查询之前就已经被删除掉了。出现这种情况的原因是因为高水位。虽然表的数据已经删除,但是表分配的EXTENT和BLOCK没有被回收,所以在这种情况下CBO依然认为有那么多的数据在表中。

& 说明:

有关动态采样的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2139284/

 

本文选自《Oracle程序员面试笔试宝典》,作者:小麦苗

640?wx_fmt=gif

---------------优质麦课------------

640?wx_fmt=png

详细内容可以添加麦老师微信或QQ私聊。

640?wx_fmt=gif

About Me:小麦苗

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/

● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

● QQ:646634621  QQ群:618766405

● 提供OCP、OCM和高可用部分最实用的技能培训

● 题目解答若有不当之处,还望各位朋友批评指正,共同进步

640?wx_fmt=gifDBA宝典

长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。

640?wx_fmt=gif

640?wx_fmt=gif

640?wx_fmt=png

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lihuarongaini/article/details/100516536

智能推荐

转Configure,Makefile.am, Makefile.in, Makefile文件之间关系_ren911的博客-程序员秘密

  1.autoscan (autoconf): 扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。     your source files --> [autoscan*] --> [configure.scan] --> configure.ac 2.aclocal (automake):根据已经安装的宏,用户定义宏和acinclude.m4文件中的宏将configure.ac文件所需要的宏集中定

字符串拼接还在用StringBuilder?快试试Java8中的StringJoiner吧,真香!_Java知音_的博客-程序员秘密

前言之前,我们经常会通过StringBuffer或者StingBuilder对字符串进行拼接,但是你知道Java8中推出的StringJoiner吗?它比前者更加优美、灵活,如果你现在还使...

【LeetCode】66. 加一_20英里法则的博客-程序员秘密

思路:第一,通过数组转换成数字加一,然后再转回数组思路二:直接用数组class Solution { public int[] plusOne(int[] digits) { for (int i = digits.length - 1; i >= 0; i--) { if (digits[i] != 9) { digits[i]++; return digits; } digit.

fatal: unable to access ‘https://github.com/nhn/raphael.git/‘: OpenSSL SSL_read: Connection was rese_多学学习吧的博客-程序员秘密

git拉取的vue项目,npm install 报错 :fatal: unable to access ‘https://github.com/nhn/raphael.git/’: OpenSSL SSL_read: Connection was reset, errno 10054执行:git config --global http.sslVerify false

机器学习中你不得不知道的数学符号表示_boldsymbol_因吉的博客-程序员秘密

最近在补一些机器学习的理论基础,因此把常用的符号做一个总结。当然,不同的子方向可能有些许区别。1 标量向量及矩阵2 自然数3 定义4 集合5 导数6 函数

【深度学习_1.3】搭建浅层神经网络模型_fourierLouis的博客-程序员秘密

目的:搭建一层隐藏层的浅层神经网络【准备】1.导入相关包import xxxx2.加载数据集X, Y = load_planar_dataset()3.查看数据plt.scatter(X[0, :], X[1, :], c=Y, s=40, cmap=plt.cm.Spectral);[image]4.查看数据集dimshape_X = X.shapeshape_Y = Y.shapem = X....

随便推点

工程导论4_酒竹子6113的博客-程序员秘密

1.软件工程师.软件工程师英文是Software Engineer,是从事软件职业的人员的一种职业能力的认证,通过它说明具备了工程师的资格。软件工程师是从事软件开发相关工作的人员的统称。它是一个广义的概念,包括软件设计人员、软件架构人员、软件工程管理人员、程序员等一系列岗位,工作内容都与软件开发生产相关。软件工程师的技术要求是比较全面的,除了最基础的编程语言(C语言/C++/JAVA等)、数据...

java任务运行报401错误原因_401的错误分析_Travel Back的博客-程序员秘密

在接口的测试中,经常会遇到客户端向服务端发送一个请求,服务端返回401的错误,那么今天本文章就来说明在接口测试中如何分析以及解决该问题。我们知道在HTTP返回的状态码中,401错误表示的是被请求的页面需要用户名和密码。401的错误详细的可以描述为:客户端发送请求抖到服务端,页面需要验证服务端会返回401的错误,见如下的错误信息:401 UNAUTHORIZEDHeadersContent-Type...

Moment.js日期处理库的使用_孙叫兽的博客-程序员秘密

Moment.jsMoment.js是一个轻量级的JavaScript时间库,它方便了日常开发中对时间的操作,提高了开发效率。这个在一些金融保险公司会经常用到,比如一下时间的格式化处理,时...

JAVA冒泡排序_我是小枝程序员的博客-程序员秘密

最近看了一篇很认真的排序解析,写的十分详细而且通俗易懂,非常值得收藏一、冒泡排序比较原理:比较两个相邻的元素,将值大的元素交换至右端。比较思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。...

studio构建错误Element uses-permission#android.permission.ACCESS_NETWORK_STATE at AndroidManifest.xml:38:5-79 dupli_lizhanqihd的博客-程序员秘密

今天在项目构建的时候遇到了如下报错:Element uses-permission#android.permission.ACCESS_NETWORK_STATE at AndroidManifest.xml:38:5-79 dupli没找到好的解决方案,仔细一看是清单文件的权限问题,于是检查,后发现权限声明重复,删除重复的留下一个即可

不同svn路径下的文件夹内容替换_svn替换文件_satellite13的博客-程序员秘密

在项目中,需要将一个svn上的文件checkout下来,替换另一个svn上的对应文件。如果直接cp过去,会发现替换的文件无法commit到新svn。通过svn info命令发现,文件的svn路径依然是原来svn的。      碰到该问题,可通过如下步骤进行操作:(自己做个记录,以备将来复用)1、删除文件下名为.svn的隐藏文件。.svn文件是subversion的版本控制信息文件,.svn

推荐文章

热门文章

相关标签