您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
陈焕生:深入理解Oracle 的并行执行(五)
 
作者 陈焕生 火龙果软件  发布于 2015-3-6
  3463  次浏览      34
 

并行执行计划中典型的串行点

现实世界中,由于使用不当,并行操作无法并行,或者并行执行计划效率低下,没有获得期望的性能提升。本节举几个典型例子。

  1. 在sql中使用rownum,导致出现PX SEND 1 SLAVE操作,所有数据都需要分发到一个PX进,以给每一行记录赋值一个唯一的rownum值,以及BUFFER SORT等阻塞操作。
  2. 使用用户自定义的pl/sql函数,函数没有声明为parallel_enable,导致使用这个函数的sql无法并行。
  3. 并行DML时,没有enable parallel dml,导致DML操作无法并行。

Rownum,导致并行执行计划效率低下 

在’数据倾斜对不同分发方式的影响’小节中,我们新建一个表lineorder_skew把lineorder的lo_custkey列90%的值修改为-1。因为lo_custkey是均匀分布的,我们可以通过对lo_custkey列求模,也可以通过对rownum求模,把90%的数据修改为-1。使用如下的case when语句:

通过以下的建表sql来测试两种用法时的sql执行性能,并行度为16。 

不使用rownum时,create table执行时间为1分钟,db time为15.1分钟。QC只分配了一组 PX进程,每个蓝色的PX进程以基于数据块地址区间为单位,并行扫描lineorder表,收集统计信息,并加载到lineorder_skew1表。没有数据需要分发,每个PX进程一直保持活跃,这是最有效率的执行路径。 

大部分时间,AAS=16。 

使用rownum时,create table执行时间为22.3分钟,db time为38.4分钟。SQL的执行时间为使用lo_orderkey时的22倍。

执行计划中出现两组PX进程,PX SEND 1 SLAVE和BUFFER SORT两个操作在之前的测试没有出现过。根据跟随table queue顺序的原则,我们来阅读这个执行计划: 

  1. 蓝色的PX进程并行扫描lineorder,通过tablequeue0把所有数据分发给一个红色的PX进程 (第10~12行)。因为rownum是一个伪列,为了保证每一行记录拥有一个唯一行号,对所有数据的rownum赋值这个操作只能由一个进程完成,为rownum列赋值成为整个并行执行计划的串行点。这就是出现PX SEND 1 SLAVE操作,性能急剧下降的原因。这个例子中,唯一活跃的红色PX进程为实例1 p008进程。Lineorder的300M行记录都需要发送到实例1 p008进程进行rownum赋值操作,再由这个进程分发给16个蓝色的PX进程进行数据并行插入操作。
  2. 实例1 p008进程接收了16个蓝色PX进程分发的数据,给rownum列赋值(第8行count操作)之后,需要通过tablequeue1把数据分发给蓝色的PX进程。但是因为通过tablequeue0的数据分发的还在进行,所以执行计划插入一个阻塞点BUFFER SORT(第7行),把rownum赋值之后的数据缓存到临时空间,大小为31GB。
  3. Tablequeue0的数据分发结束之后,实例1 p008把31GB数据从临时空间读出,通过tablequeue1分发给16个蓝色的PX进程进行统计信息收集和插入操作

红色的PX进程只有实例1 p008是活跃的。消耗了16.7分钟的db time。对于整个执行计划而言,两次数据分发也消耗了大量的db cpu。通过Table queue 0把300M行记录从16个蓝色的PX进程分发给1个红色的 PX 进程。通过Table queue 1把300M行记录从1个红色的PX进程分发给16个蓝色的PX进程。 

虽然DoP=16,实际AAS=1.5,意味着执行计划效率低下。 

现实世界中,在应用中应该避免使用rownum。Rownum的生成操作会执行计划的串行点,增加无谓的数据分发。对于使用rownum的sql,提升并行度往往不会改善性能,除了修改sql代码,没有其他方法。 

自定义PL/SQL函数没有设置parallel_enable,导致无法并行 

Rownum会导致并行执行计划出现串行点,而用户自定义的pl/sql函数,如果没有声明为parallel_enable,会导致sql只能串行执行,即使用hint parallel指定sql并行执行。我们来测试一下,创建package pk_test,包含函数f,返回和输入参数一样的值。函数的声明中没有parallel_enable,不支持并行执行。

以下例子中在where语句中使用函数pk_test.f,如果在select列表中使用函数pk_test.f,也会导致执行计划变成串行执行。 

查询执行时间为54秒,db time也为54秒。虽然我们指定使用Dop=4并行执行,执行计划实际是串行的。 

在函数的声明时设置parallel_enable,表明函数支持并行执行,再次执行sql。 

此时查询的执行时间为12秒,db time为46.4秒。并行执行如期发生,并行度为4。 

除非有特殊的约束,创建自定义pl/sql函数时,都应该声明为parallel_enable。pl/sql函数声明时没有设置parallel_enable导致无法并行是一个常见的问题,我曾在多个客户的系统中遇到。在11g中,这种情况发生时,执行计划中可能会出现PX COORDINATOR FORCED SERIAL操作,这是一个明显的提示; 或者你需要通过sql monitor报告定位这种问题。仅仅通过dbms_xplan。display_cursor检查执行计划是不够的,这种情况执行计划的note部分,还是会显示DoP=4。 /p>

并行DML,没有enable parallel dml,导致DML操作无法并行。 

这是ETL应用中常见的问题,没有在session级别enable或者force parallel dml,导致dml操作无法并行。使用customer的1.5M行数据演示一下。 

建一个空表customer_test: 

我们使用并行直接路径插入的语句作为例子。分别执行两次insert,第一次没有enable parallel dml,insert语句如下: 

Insert语句执行时间9秒。虽然整个语句的并行度为4,但是执行计划中,第2行直接路径插入操作LOAD AS SELECT是串行执行的。 

此时执行计划的Note部分会显示PDML没有启用:

启用parallel dml之后,重新执行insert语句。 

此时insert语句执行时间为3秒,执行计划中第三行,LOAD AS SELECT操作是可以并行的。

小节

我列举了使用并行执行时,常见的三种问题:

  1. 使用rownum。
  2. 自定义pl/sql函数没有声明parallel_enable。
  3. 并行DML时没有enable parallel dml。

希望通过以上三个例子,希望读者对调试并行执行计划有一个更直观的感受。处理并行执行的问题,sql monitor报告是最好的分析工具。对于并行DDL和DML,Oracle本身有一些限制,可以参见官方文档3,比如:

  1. 表上的触发器或者外键约束可能导致DML无法并行。
  2. 包含LOB字段的非分区表,不支持并行DML和DDL;包含LOB字段的分区表,只支持分区间的并行DML和DDL。
  3. 远程表(通过db link)不支持并行DML;临时表不支持并行update,merge,delete。

总结

这篇长长的文章更像是我在Real-World Performance Group的工作总结。在大量实际项目中,我们发现很多开发或者DBA并没有很好理解并行执行的工作原理,设计和使用并行执行时,往往也没取得最佳的性能。对于并行执行,已经有很多的Oracle书籍和网上文章讨论过,在我看来,这些内容更偏重于并行执行原理的解释,缺乏实际的使用案例。我希望在本文通过真实的例子和数据,以最简单直接的方式,向读者阐述Oracle并行执行的核心内容,以及在现实世界中,如果规避最常见的使用误区。也希望本文所使用sql monitor报告分析性能问题的方法,对读者有所启示! 如果现在你对以下并行执行的关键点,都胸有成竹的话,我相信现实世界中Oracle的并行执行问题都不能难倒你。

  • Oracle并行执行为什么使用生产者-消费者模型。
  • 如何阅读并行执行计划。
  • 不同的数据分发方式分别适合什么样的场景。
  • 使用partition wise join和并行执行的组合提高性能。
  • 数据倾斜会对不同的分发方式带来什么影响。
  • 由于生产者-消费者模型的限制,执行计划中可能出现阻塞点。
  • 布隆过滤是如何提高并行执行性能的。
  • 现实世界中,使用并行执行时最常见的问题。

致谢

本文目前的内容和质量,源于对初稿的多次审校和迭代。本文的两个难点,1)连续hash分发时出现阻塞点; 2)hash分发时使用布隆过滤的具体过程,得到了我英国同事Mike Hallas的解答和确认。我的同事董志平对初稿的做了详细的审校,指出多处纰漏。本文的一些内容是在他的建议下增加的,比如Partition Wise Join时,DoP大于分区数时partition wise join会失效,比如replicate方式为什么不能完全替代broadcast分发。我的同事徐江和李常勇,我的朋友蒋健阅读初稿之后,也提供了诸多反馈,在此一并感谢! 

   
3463 次浏览       34
相关文章

基于EA的数据库建模
数据流建模(EA指南)
“数据湖”:概念、特征、架构与案例
在线商城数据库系统设计 思路+效果
 
相关文档

Greenplum数据库基础培训
MySQL5.1性能优化方案
某电商数据中台架构实践
MySQL高扩展架构设计
相关课程

数据治理、数据架构及数据标准
MongoDB实战课程
并发、大容量、高性能数据库设计与优化
PostgreSQL数据库实战培训
最新活动计划
嵌入式软件架构设计 12-11[北京]
LLM大模型与智能体开发实战 12-18[北京]
嵌入式软件测试 12-25[北京]
AI原生应用的微服务架构 1-9[北京]
AI大模型编写高质量代码 1-14[北京]
需求分析与管理 1-22[北京]

MySQL索引背后的数据结构
MySQL性能调优与架构设计
SQL Server数据库备份与恢复
让数据库飞起来 10大DB2优化
oracle的临时表空间写满磁盘
数据库的跨平台设计
更多...   


并发、大容量、高性能数据库
高级数据库架构设计师
Hadoop原理与实践
Oracle 数据仓库
数据仓库和数据挖掘
Oracle数据库开发与管理


GE 区块链技术与实现培训
航天科工某子公司 Nodejs高级应用开发
中盛益华 卓越管理者必须具备的五项能力
某信息技术公司 Python培训
某博彩IT系统厂商 易用性测试与评估
中国邮储银行 测试成熟度模型集成(TMMI)
中物院 产品经理与产品管理
更多...