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 ...
随机推荐
- Linux下Oracle单实例配置多监听
Oracle单实例配置多监听 一.前言 有时候我们项目中需要使用Oracle数据库,同时要需要不同的数据源,而Oracle不像Mysql那样直接建个库即可,Oracle是以账号为单位,可以理解为一个账 ...
- 文心一言 VS 讯飞星火 VS chatgpt (64)-- 算法导论6.5 3题
文心一言 VS 讯飞星火 VS chatgpt (64)-- 算法导论6.5 3题 三.要求用最小堆实现最小优先队列,请写出 HEAP-MINIMUM.HEAP-EXTRACT-MIN.HEAP DE ...
- go项目实现在配置文件实现配置项统一管理
转载请注明出处: go项目中实现配置项统一管理,实现逻辑:将 配置项整理为一个json的数据结构,并保存到go.conf文件中,然后在go项目启动main方法中加载 go.conf 文件,读取go.c ...
- Django: django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "game-detail".
错误原因:在序列化时,使用了参数`url`,但在`urls.py`文件中,没有使用命名 # urls.py from django.urls import path from RESTSerializ ...
- 采用PCA算法&KMeans算法来实现用户对物品类别的喜好细分(菜篮子分析)(附带数据集下载)
实现该项目的流程如下 """ 项目:用户对物品类别的喜好细分(菜篮子分析) 主算法:PCA降维算法 KMeans算法 总思路 1.导包 2.获取数据 3.数据处理 5.特 ...
- Avalonia 列表拖拽替换
实现目标,在一个ListBox中选择一个子项进行拖拽到另一个ListBox中,拖拽到某一子项区域进行替换 下面是axaml代码 1 <ListBox 2 Name="consumabl ...
- cesium中限制地图浏览范围
https://blog.csdn.net/qq_42740164/article/details/119375782?ops_request_misc=%257B%2522request%255Fi ...
- 牛客小白月赛65 D题 题解
原题链接 题意描述 一共有两堆石子,第一堆有 \(a\) 个,第二堆有 \(b\) 个,牛牛和牛妹轮流取石子,牛牛先手,每次取石子的时候只能从以下 \(2\) 种方案种挑一种来取(对于选择的方案数必须 ...
- 带你走进数仓大集群内幕丨详解关于作业hang及残留问题定位
本文分享自华为云社区<[带你走进DWS大集群内幕]大集群通信:作业hang.残留问题定位>,作者: 雨落天穹丶. 前言: 测试过程中,我们会遇到这样一种情况,我的作业都执行很久了,为啥还不 ...
- [nginx]防范空主机头
空主机头防范主要是防止别人恶意将域名解析到服务器IP上. 配置示例 方式一,增加vhost # http的空主机头防范 server { listen 80 default; server_name ...