本文分享自华为云社区《【调优实践】SQL改写消除相关子查询》,作者: 门前一棵葡萄树 。

一、子查询

GaussDB(DWS)根据子查询在SQL语句中的位置把子查询分成了子查询、子链接两种形式。

  • 子查询SubQuery:对应于查询解析树中的范围表RangeTblEntry,更通俗一些指的是出现在FROM语句后面的独立的SELECT语句。
  • 子链接SubLink:对应于查询解析树中的表达式,更通俗一些指的是出现在where/on子句、targetlist里面的语句。

1.1 非相关子查询

子查询的执行不依赖于外层父查询的任何属性值。这样子查询具有独立性,可独自求解,形成一个子查询计划先于外层的查询求解。示例:

select t1.c1,t1.c2
from t1
where t1.c1 in (
select c2
from t2
where t2.c2 IN (2,3,4)
);

1.2 相关子查询

子查询的执行依赖于外层父查询的一些属性值(如下列示例t2.c1 = t1.c1条件中的t1.c1)作为内层查询的一个AND-ed条件。这样的子查询不具备独立性,需要和外层查询按分组进行求解。

select t1.c1,t1.c2
from t1
where t1.c1 in (
select c2
from t2
where t2.c1 = t1.c1 AND t2.c2 in (2,3,4)
);

二、调优实战

2.1 案例:

UPDATE t1
SET (c1,c2)=(
SELECT COALESCE(t2.c1, t1.c2),c2 FROM t2 WHERE t1.i1 = t2.i1 -- 相关标量子查询
);

其中子查询SELECT COALESCE(t2.c1, t1.c2),c2 FROM t2 WHERE t1.i1 = t2.i1 依赖于外层父查询的t1表,因此属于相关子查询。执行计划:

                                                                           QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------
id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs
----+-----------------------------------------------+----------------+--------+--------+------------+----------------+----------+---------+---------+---------
1 | -> Streaming (type: GATHER) | 8.998 | 0 | 1 | | 24KB | | | 17 | 9.83
2 | -> Update on public.t1 | [0.086, 0.096] | 2 | 2 | | [308KB, 308KB] | | | 17 | 9.74
3 | -> Seq Scan on public.t1 | [0.058, 0.074] | 2 | 2 | | [32KB, 32KB] | 1MB | | 17 | 3.73
4 | -> Result [3, SubPlan 1] | [0.033, 0.034] | 2 | 10 | | [16KB, 16KB] | 1MB | | 6 | 1.36
5 | -> Materialize | [4.167, 4.458] | 20 | 10 | | [16KB, 16KB] | 16MB | [24,24] | 6 | 1.36
6 | -> Streaming(type: BROADCAST) | [4.105, 4.406] | 10 | 10 | | [48KB, 48KB] | 2MB | | 6 | 1.33
7 | -> Seq Scan on public.t2 | [0.013, 0.013] | 5 | 5 | | [32KB, 32KB] | 1MB | | 6 | 1.02
8 | -> Result [3, SubPlan 2] | [0.006, 0.021] | 2 | 10 | | [16KB, 16KB] | 1MB | | 6 | 1.36
9 | -> Materialize | [0.055, 0.061] | 20 | 10 | | [16KB, 16KB] | 16MB | [24,24] | 6 | 1.36
10 | -> Streaming(type: BROADCAST) | [0.034, 0.040] | 10 | 10 | | [48KB, 48KB] | 2MB | | 6 | 1.33
11 | -> Seq Scan on public.t2 | [0.005, 0.009] | 5 | 5 | | [32KB, 32KB] | 1MB | | 6 | 1.02

2.2 子查询消除

改写策略就是解除子查询与父查询依赖关系,改写方案参考:

UPDATE t1
SET (c1,c2)=(t3.c1,t3.c2)
FROM (
SELECT t2.i1,COALESCE(t2.c1, t1.c2) c1,t2.c2 FROM t1,t2 WHERE t1.i1 = t2.i1
)t3
WHERE t1.i1 = t3.i1;

改写后,子查询独立,不再依赖父查询中元素。执行计划:

                                                                              QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
id | operation | A-time | A-rows | E-rows | E-distinct | Peak Memory | E-memory | A-width | E-width | E-costs
----+-----------------------------------------------------+----------------+--------+--------+------------+----------------+----------+---------+---------+---------
1 | -> Streaming (type: GATHER) | 13.141 | 0 | 1 | | 24KB | | | 33 | 10.56
2 | -> Update on public.t1 | [6.242, 6.362] | 2 | 2 | | [308KB, 308KB] | | | 33 | 10.47
3 | -> Streaming(type: RESTORE) | [6.186, 6.310] | 2 | 2 | | [48KB, 48KB] | 2MB | | 33 | 4.46
4 | -> Nested Loop (5,11) | [4.082, 4.801] | 2 | 2 | | [32KB, 32KB] | 1MB | | 33 | 4.44
5 | -> Streaming(type: BROADCAST) | [3.804, 4.541] | 4 | 4 | | [48KB, 48KB] | 2MB | | 27 | 2.36
6 | -> Nested Loop (7,8) | [2.972, 4.267] | 2 | 2 | | [32KB, 32KB] | 1MB | | 27 | 2.20
7 | -> Seq Scan on public.t1 | [0.010, 0.011] | 2 | 2 | | [16KB, 16KB] | 1MB | | 14 | 1.01
8 | -> Materialize | [2.724, 4.055] | 6 | 4 | | [16KB, 16KB] | 16MB | [28,28] | 13 | 1.17
9 | -> Streaming(type: BROADCAST) | [2.667, 4.008] | 4 | 4 | | [48KB, 48KB] | 2MB | | 13 | 1.17
10 | -> Seq Scan on public.t1 | [0.008, 0.012] | 2 | 2 | | [16KB, 16KB] | 1MB | | 13 | 1.01
11 | -> Materialize | [0.018, 0.022] | 12 | 5 | | [16KB, 16KB] | 16MB | [32,32] | 14 | 2.03
12 | -> Seq Scan on public.t2 | [0.007, 0.009] | 5 | 5 |

点击关注,第一时间了解华为云新鲜技术~

数仓调优实践丨SQL改写消除相关子查询的更多相关文章

  1. [转载]Java 应用性能调优实践

    Java 应用性能调优实践 Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具 ...

  2. MySQL数据库的性能分析 ---图书《软件性能测试分析与调优实践之路》-手稿节选

    1  .MySQL数据库的性能监控 1.1.如何查看MySQL数据库的连接数 连接数是指用户已经创建多少个连接,也就是MySQL中通过执行 SHOW  PROCESSLIST命令输出结果中运行着的线程 ...

  3. 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL

    周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...

  4. 记一次SQL调优/优化(SQL tuning)——性能大幅提升千倍以上

    好久不写东西了,一直忙于各种杂事儿,恰巧昨天有个用户研发问到我一个SQL调优的问题,说性能太差,希望我能给调优下,最近有些懒,可能和最近太忙有关系,本来打算问问现在的情况,如果差不多就不调了,那哥们儿 ...

  5. JVM性能调优实践——JVM篇

    前言 在遇到实际性能问题时,除了关注系统性能指标.还要结合应用程序的系统的日志.堆栈信息.GClog.threaddump等数据进行问题分析和定位.关于性能指标分析可以参考前一篇JVM性能调优实践-- ...

  6. 软件性能测试分析与调优实践之路-Web中间件的性能分析与调优总结

    本文主要阐述软件性能测试中的一些调优思想和技术,节选自作者新书<软件性能测试分析与调优实践之路>部分章节归纳. 在国内互联网公司中,Web中间件用的最多的就是Apache和Nginx这两款 ...

  7. PB 级大规模 Elasticsearch 集群运维与调优实践

    PB 级大规模 Elasticsearch 集群运维与调优实践 https://mp.weixin.qq.com/s/PDyHT9IuRij20JBgbPTjFA | 导语 腾讯云 Elasticse ...

  8. 软件性能测试分析与调优实践之路-Java应用程序的性能分析与调优-手稿节选

    Java编程语言自从诞生起,就成为了一门非常流行的编程语言,覆盖了互联网.安卓应用.后端应用.大数据等很多技术领域,因此Java应用程序的性能分析和调优也是一门非常重要的课题.Java应用程序的性能直 ...

  9. OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  10. 初次使用SQL调优建议工具--SQL Tuning Advisor

    在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning Advisor :STA),它是新的DBMS_SQLTUNE包. 使用STA一定要保证优化器是CBO模式下 ...

随机推荐

  1. 基于ZXing.NET实现的二维码生成和识别客户端

    一.前言 ZXing.Net的一个可移植软件包,是一个开源的.多格式的1D/2D条形码图像处理库,最初是用Java实现的.已经过大量优化和改进,它已经被手动移植.它与.Net 2.0..Net 3.5 ...

  2. 虹科技术|Redis企业版数据库:实现金融服务IT现代化!

    随着新冠肺炎和技术创新推动企业进入新的数字时代,金融行业客户现在需要一种快速.简单且根据需求量身定制的数字银行体验.这就需要银行进行转型,以提供更加数字化的服务,但无论战略.方法,还是满足消费者极高期 ...

  3. 虹科案例 | 石油天然气行业CFD高性能计算解决方案

    公司简介 DNV GL 是全球领先的能源.石油和海事行业风险管理及资产绩效提升的软件供应商,主要为客户提供全面的风险管理和各类评估认证服务,认证涉及信息通信技术.汽车及航空天.食品与饮料.医疗等方面. ...

  4. 如何使用SHC对Shell脚本进行封装和源码隐藏

    在许多情况下,我们需要保护我们的shell脚本源码不被别人轻易查看.这时,使用shc工具将shell脚本编译成二进制文件是一个有效的方法.本文将详细介绍如何在线和离线条件下安装shc,并将其用于编译你 ...

  5. LooklessControl

    Lookless controls vs User Controls. Lookless controls usage patterns(LooklessControl与UserControl的比较. ...

  6. Python使用pymysql和xlrd2将Excel数据导入MySQL数据库

    在数据处理和管理中,有时候需要将Excel文件中的数据导入到MySQL数据库中进行进一步的分析和操作.本文将介绍如何使用Python编程语言实现这个过程. 导入所需库 import xlrd2 # 导 ...

  7. js执行过程之上下文对象(Context)

    在js的学习中,我们已经不满足于仅了解js的基础知识,而是开始追求更深层次的学习.因为你会发现,仅了解js的基础知识,在开发项目的过程中是远远不够的.今天就来介绍一下在js执行过程中的一些相关内容了. ...

  8. C语言,中国有句俗语:“三天打鱼两天晒网”,某人从1990年1月1日起开始“三天打鱼两天晒网”。问这个人在以后的某一天是在“打鱼”还是在“晒网”?

    #include<stdio.h> long y_tianshu(int y); int n_tianshu(int y, int n); int T(int y, int n,int d ...

  9. Android 实现APP可切换多语言

    原文: Android 实现APP可切换多语言 - Stars-One的杂货小窝 如果是单独给app加上国际化,其实很容易,创建对应的国家资源文件夹即可,如values-en,values-pt,ap ...

  10. maven使用指定的pom文件构建子模块

    有条件的同学建议直接浏览原文: https://stackoverflow.com/questions/33396390/custom-pom-xml-filename-in-maven-multim ...