暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

AI播客学SQL系列5.12: Oracle统计信息收集:并行 vs 并发,别再傻傻分不清!

78
本文是基于笔者墨天轮专栏课程《Oracle降龙十八掌之SQL性能诊断和调优》生成的AI播客和PPT课件,希望对大家有所帮助和提供一点儿价值,同时欢迎大家订阅原课程。

聚焦Oracle数据库中统计信息收集的性能优化,详解并行与并发两种方式的差异及应用场景。


随着现在应用数据越来越多,表的数量也在不断增长,传统那种串行收集统计信息的方式效率越来越低了。没错,这就是为什么Oracle后来推出了并行和并发这两种收集方式。其实这两个概念经常被人搞混,但其实区别挺大的。
对对对,我先给你打个比方啊。并行收集就像是...呃...就像是一个人在搬大箱子,但是他不是一个人搬,而是叫了好几个帮手一起搬这一个箱子。而并发呢,就像是好几个人同时在搬不同的箱子。
嗯,这个比喻很形象。
哦?有什么改进?
就是默认值变成了DBMS_STATS.AUTO_DEGREE
。什么意思呢?就是Oracle会根据对象的大小和并行参数的设置情况,自动决定用多少个并行进程。
哦!自动调优啊!那用户还是可以手动指定的是吧?
当然可以。比如你可以设置DEGREE=4
,就是强制用4个并行进程。不过要注意的是,Oracle并不能并行收集所有类型的索引。
哪些索引不行呢?
主要是三类:
  • cluster indexes
  • domain indexes
  • bitmap join indexes
这几种索引类型因为它们的结构特性,不适合并行处理。
并行收集与DEGREE参数详解
明白了。那我们再说说并发收集吧,这个更复杂一些。
是的,并发收集是从11.2.0.2版本才开始支持的。它解决的问题是什么呢?就是说,并行收集只是解决了单个对象内部的问题,但如果我要收集100个表的统计信息,还是得一个接一个地处理。
是啊,这多浪费时间啊!
所以并发收集就来了。它允许同时启动多个Job,真正实现了多个对象的同时处理。而且从12.1.0.1版本开始,连自动统计收集任务都能用上这个功能了。
哇,那要启用这个功能,需要设置哪些参数呢?
主要有三个。
  1. 首先是CONCURRENT参数,需要通过DBMS_STATS.SET_GLOBAL_PREFS
    来设置。
  2. 其次是JOB_QUEUE_PROCESSES参数,这是控制最大Job数量的。
  3. 最后还要启用Resource Manager
等等,是不是所有版本的设置都一样?
不是的。在11.2.0.2到11.2.0.4的版本上,CONCURRENT参数只能设置成TRUE或FALSE。但从12c开始,可以设置更灵活的值了。
说到这儿,我想起一个实际案例。有个用户反馈说,他在生产环境用了并发收集,但是监控发现好像并没有真正的并发...
这种情况确实常见。其实Oracle内部有个优化机制,它会根据表的大小来决定是否真的创建独立的Job。
哦?怎么个逻辑?
就是说,如果某个表或者分区特别小,Oracle为了节省资源,会把多个小对象合并到一个Job里执行。这样在外部监控的时候,就看不到明显的并发效果了。
原来如此!那如果是分区表呢?
分区表的处理比较特殊。Oracle会为每个分区分配一个Job,但为了避免死锁,分区表的处理是排队的——一次只能处理一个分区表,其他要等前面的处理完了才能开始。
这个设计挺合理的。那在监控方面,我们能看到什么呢?
可以通过查看作业队列来监视。比如说,你会看到针对每个对象都有一个单独的Job在执行。如果是分区表,还会有一个协调Job加上各个分区的Job。
并发收集的配置与监控
还有一个有意思的问题。我看到材料里提到了SE版本,就是Standard Edition,这个版本能用并发收集吗?
这是个好问题。虽然Resource Manager这个功能是Enterprise Edition专有的,但因为Standard Edition内部也会用到Resource Manager的一些能力,所以实际上是可以并发执行的。
就是说,即使没有显式地启用Resource Manager,只要设置了CONCURRENT为TRUE,它还是会工作的?
对,就是这个意思。不过要注意,11.2.0.3到11.2.0.4版本上,CONCURRENT参数默认是OFF的,需要手动开启。
嗯,那在实际操作中,还有没有什么需要注意的地方?
有,一个很重要的点是并行和并发的组合使用。如果两个都用,效率会更高,特别是在处理非常大的表或者分区的时候
那要怎么设置?
就是同时设置DEGREE和CONCURRENT两个参数。不过有个技巧,就是要把parallel_adaptive_multi_user
参数设为False。
为什么?这个参数不是自动调整并行度的吗?
因为在并发模式下,Oracle已经有自己的调度机制了。如果两个自适应机制同时工作,反而会互相干扰,可能导致并行度不如预期的效果。
这个细节很重要!还有没有其他限制条件?
嗯,在11.2.0.3的版本上,有一个batching threshold的概念。就是当对象太小的时候,Oracle会把它们合并到一个Job里处理,而不是真的并发。
这个threshold是多少呢?能调整吗?
很遗憾,这个阈值是Oracle内部决定的,用户不能直接修改。它受环境、资源利用率等多种因素影响。
那有没有办法绕过这个限制,强制让某些大表并发执行?
其实可以通过设置PARALLEL参数来间接实现。因为大对象会自动获得更多的并行度,即使JOB数量不多,单个Job的效率也很高。
还有一个常见问题——如何限定只对一部分表进行并发收集?
这个可以通过obj_filter_list参数来实现。你可以构造一个OBJECTTAB,里面包含你想要并发收集的表名,然后把这个列表传给DBMS_STATS。
具体怎么写SQL语句?
大概是这样:先创建一个表或者视图,存放你要收集的表名,然后调用DBMS_STATS.SET_TABLE_PREFS
或者SET_SCHEMA_PREFS
,结合CONCURRENT参数使用。
听起来很灵活。不过在实际应用中,是不是还有其他要考虑的因素?
当然有。比如作业队列进程数(JOB_QUEUE_PROCESSES)要设置够大,否则并发Job太多会导致排队。还有Resource Manager的计划要配置好,确保有足够的系统资源。
嗯,看来并发收集确实是个挺复杂的话题。不过总的来说,对于大数据量的环境,这绝对是个提升性能的好方法。
是的,特别是当你有成百上千个表需要定期收集统计信息的时候,并发模式能节省大量时间。当然,前提是要根据实际情况合理配置参数。
好了,今天咱们详细聊了Oracle数据库中并行和并发收集统计信息的方法,从基本概念到实际应用,从参数设置到常见问题。

好,今天的分享就到这里。感谢大家的收听,我们下期再见!



文章转载自SQL和数据库技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论