SQL改写案例2
postgresql 并没有像 oracle 、dm 有这么丰富的 hint,在不改 sql 的情况下能干预执行计划。
如果想学好 postgresql、kingbase、MySQL 的sql 调优,sql 的等价改写是必须要掌握的技巧,今天分享一个案例,简单的标量子查询改左连接。
环境介绍:

学生表 和 课程表,表结构、索引、表的数据量如上图。
这边我用的是 pg15 的版本,因为 pg15优化器性能的提升在pg12以及之前的版本非常大, 笔者有测试过不同场景的复杂 sql 。
慢sql以及执行计划如下:
explain analyze select sc.CLS_ID,
sc.CLS_NAME,
(select count(s.STU_ID) from STUDENT s where s.STU_CLASSID = sc.CLS_ID)
from STU_CLASS sc;

该sql的语义从2千万行的学生表统计出不同课程id的学员分别是多少,执行时间消耗了1m8s, 很慢。
但是这条sql 笔者在相同配置的 orace 11.2.0.4 环境中跑过,oracle 执行时间需要 1m51s。
这点可以看出 pg15 优化器性能提升是非常巨大的,甚至感觉可以吊打市面上除了 ORACLE 以外任何关系型数据库的sql优化器。(个人想法,有兴趣朋友可以测试下)
话说回来,这条sql 在不改写的情况下,加索引或者是使用 hint 都不好使,就需要左连接方式等价的方式改写这条sql。
-- 改写1、标量子查询改左连接:
explain analyze
select sc.CLS_ID,
sc.CLS_NAME,
count(s.stu_id)
from stu_class sc left join student s on (sc.cls_id = s.stu_classid)
group by sc.CLS_ID, sc.CLS_NAME;

-- 改写2、使用分析函数 + 左连接改写
explain analyze
select distinct sc.CLS_ID,
sc.CLS_NAME,
count(s.stu_id) over (partition by sc.CLS_ID,sc.CLS_NAME) count_stu_id
from stu_class sc
left join student s on (sc.cls_id = s.stu_classid);

可以看到改写1、标量子查询改左连接执行速度最快,原来sql 需要1分8秒的执行时间,下降到 7.7 s 的执行时间,已经是巨大的提升,Oracle中执行该 sql 需要 6s。
再看改写2、使用分析函数 + 左连接改写,虽然降低到 34s 的执行时间,这种改法在本案例中效果并不出众,但是也有缩减一半执行时间的提升效果。
注意:标量子查询等价改下,使用分析函数并不是最佳手段,这里演示这种改法只是为了扩展大家sql改写的思路,实际情况下,自连接查询使用分析函数等价改写的效果性能是最好的,因为表只访问了一次。
从上面的案例可以知道,生产环境中大部分标量子查询的sql都可以等价改写成左连接,这样程序运行起来性能会有比较大的提升。
通过以上sql案例改写的学习,给大家出个简单的改写题,大家有兴趣可以下去玩玩。
scott.emp表没有的话,可以百度,一大堆创建的语句。
select e1.empno,
e1.ename,
e1.sal,
(select sum(sal)
from EMP e2
where e2.sal >= e1.sal - 100
and e2.sal <= e1.sal) sum_sal
from emp e1;
改写要求(任意数据库改写都可以):
改写方式1:要求上面 sql 改成左连接。
改写方式2:要求上面 sql 改成分析函数 + 左连接。
改写方式3:要求上面sql 只放问表emp一次,不使用表连接。
方式1、方式2 通过上面案例的学习,相信大家很快就能做出来,方式3的改写可能就需要思考一下,如果实在想不出来也可以联系我,告诉你答案,嘿嘿!
想交流 SQL调优、PLSQL、SQL等价改写、JAVA 的朋友可以联系我 18902234014(微信同号),相互学习,共同进步。
SQL改写案例2的更多相关文章
- 数栈SQL优化案例:隐式转换
MySQL是当下最流行的关系型数据库之一,互联网高速发展的今天,MySQL数据库在电商.金融等诸多行业的生产系统中被广泛使用. 在实际的开发运维过程中,想必大家也常常会碰到慢SQL的困扰.一条性能不好 ...
- SQL注入(SQL Injection)案例和防御方案
sql注入(SQL Injection):就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. SQL注入攻击的主要危害包括:非法读取.篡 ...
- 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写
摘要:本文将系统介绍在GaussDB(DWS)系统中影响性能的坏味道SQL及SQL模式,帮助大家能够从原理层面尽快识别这些坏味道SQL,在调优过程中及时发现问题,进行整改. 数据库的应用中,充斥着坏味 ...
- SQL优化案例—— RowNumber分页
将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...
- mysql的sql优化案例
前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...
- SQL 优化案例 1
create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...
- sqlserver sql优化案例及思路
始sql: SELECT TOP 100 PERCENT ZZ.CREW_NAME AS 机组, ZZ.CREW_ID, AA.年度时间, CC.当月时间, DD.连续七天时间 AS 最近七天 FRO ...
- Hive SQL综合案例
一 Hive SQL练习之影评案例 案例说明 现有如此三份数据:1.users.dat 数据格式为: 2::M::56::16::70072, 共有6040条数据对应字段为:UserID BigInt ...
- SQL夯实基础(四):子查询及sql优化案例
首先我们先明确一下sql语句的执行顺序,如下有前至后执行: (1)from (2) on (3) join (4) where (5)group by (6) avg,sum... (7 ...
- SQL 优化案例
create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...
随机推荐
- EF6连接oracle
最近项目用到oracle,一直使用sql server,ef很方便连接mssql,但是连接oracle的方法网上很多文章,尝试很多次终于搞定,dbfirst或者codefirst也是可以的. 安装OD ...
- Mysql高级3-索引的结构和分类
一.索引概述 1.1 索引的介绍 索引index:是帮助 Mysql 高效获取数据 的 有序的数据结构,在数据之外,数据库系统维护着的满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据 ...
- 获取Rtx用户状态方法
背景:企业OA系统需要与Rtx集成,且高权限身份用户需要获取符合某一条下的所有员工rtx状态... 方案:以此背景,基于rtx sdk做二次开发, 1.后台调用RootObj.QueryUserSta ...
- @ControllerAdvice 注解使用及原理探究
最近在新项目的开发过程中,遇到了个问题,需要将一些异常的业务流程返回给前端,需要提供给前端不同的响应码,前端再在次基础上做提示语言的国际化适配.这些异常流程涉及业务层和控制层的各个地方,如果每个地方都 ...
- 使用supervisor守护freeswitch进程
一.安装supervisor yum install -y epel-release yum install -y supervisor systemctl start supervisord sys ...
- 《深入理解Java虚拟机》读书笔记:垃圾收集算法
由于垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程. 垃圾收集算法概要 1. 标记-清除算法 ...
- 开机自动打开termux以及启动termux的服务
ps:因为我们的服务是安装在平板上面的termux,客户不想维护麻烦,如果平板重启之后还需要手动启动ternux,还要开启命令启动服务,这样比较麻烦,所以研究如下操作 1.安装macroDroid 直 ...
- 纯前端导出word手写复杂表格,并还原成word。百分百还原表格。一文搞定前端表格导出为word
本次的需求是手写一个养老院老人生活能力评定表,并且要能够录入信息,最终导出 表格因为有七页所以代码很多,可以不用看表格模板的详细代码. 先贴上最终效果图 填写完导出之后 基本上实现了样式的百分百还原导 ...
- 《Python魔法大冒险》004 第一个魔法程序
在图书馆的一个安静的角落,魔法师和小鱼坐在一张巨大的桌子前.桌子上摆放着那台神秘的笔记本电脑. 魔法师: 小鱼,你已经学会了如何安装魔法解释器和代码编辑器.是时候开始编写你的第一个Python魔法程序 ...
- 使用 Sealos 一键部署高可用 MinIO,开启对象存储之旅
大家好!今天这篇文章主要向大家介绍如何通过 Sealos 一键部署高可用 MinIO 集群. MinIO 对象存储是什么? 对象是二进制数据,例如图像.音频文件.电子表格甚至二进制可执行代码.对象的大 ...