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的更多相关文章

  1. 数栈SQL优化案例:隐式转换

    MySQL是当下最流行的关系型数据库之一,互联网高速发展的今天,MySQL数据库在电商.金融等诸多行业的生产系统中被广泛使用. 在实际的开发运维过程中,想必大家也常常会碰到慢SQL的困扰.一条性能不好 ...

  2. SQL注入(SQL Injection)案例和防御方案

    sql注入(SQL Injection):就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. SQL注入攻击的主要危害包括:非法读取.篡 ...

  3. 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写

    摘要:本文将系统介绍在GaussDB(DWS)系统中影响性能的坏味道SQL及SQL模式,帮助大家能够从原理层面尽快识别这些坏味道SQL,在调优过程中及时发现问题,进行整改. 数据库的应用中,充斥着坏味 ...

  4. SQL优化案例—— RowNumber分页

    将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...

  5. mysql的sql优化案例

    前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...

  6. SQL 优化案例 1

    create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...

  7. sqlserver sql优化案例及思路

    始sql: SELECT TOP 100 PERCENT ZZ.CREW_NAME AS 机组, ZZ.CREW_ID, AA.年度时间, CC.当月时间, DD.连续七天时间 AS 最近七天 FRO ...

  8. Hive SQL综合案例

    一 Hive SQL练习之影评案例 案例说明 现有如此三份数据:1.users.dat 数据格式为: 2::M::56::16::70072, 共有6040条数据对应字段为:UserID BigInt ...

  9. SQL夯实基础(四):子查询及sql优化案例

    首先我们先明确一下sql语句的执行顺序,如下有前至后执行: (1)from  (2) on   (3) join  (4) where  (5)group by  (6) avg,sum...  (7 ...

  10. SQL 优化案例

    create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...

随机推荐

  1. 使用 FastGPT 构建高质量 AI 知识库

    作者:余金隆.FastGPT 项目作者,Sealos 项目前端负责人,前 Shopee 前端开发工程师 FastGPT 项目地址:https://github.com/labring/FastGPT/ ...

  2. 洛谷 P1336 最佳课题选择 题解

    P1336 最佳课题选择 题解 状态:考虑\(f_{i,j}\)表示前\(i\)种论文里面,一共写了\(j\)篇,的最少花费时间. 转移策略:我们一次考虑每一种论文写多少篇.假设写\(k\)篇,\(k ...

  3. [pytest]基础

    简介 The pytest framework makes it easy to write small, readable tests, and can scale to support compl ...

  4. nginx反向代理常用基本配置

    http反向代理 http { ...     server {     listen 80;         location / {         proxy_pass http://192.1 ...

  5. Programming abstractions in C阅读笔记:p84-p87

    <Programming Abstractions In C>学习第43天,p84-p87总结. 一.技术总结 1.record record也称为structure(结构体),是一种数据 ...

  6. 前后端分离中台框架 Admin.Core 学习-介绍与配置说明

    中台框架后端项目 Admin.Core 的介绍与配置说明 中台admin是前后端分离权限管理系统,Admin.Core为后端项目,基于.NET 7.0开发. 支持多租户.数据权限.动态 Api.任务调 ...

  7. Airtest遇到模拟器无法输入中文的情况该如何处理?

    此文章来源于项目官方公众号:"AirtestProject" 版权声明:允许转载,但转载必须保留原链接:请勿用作商业或者非法用途 1. 前言 最近有收到同学们的一些提问,使用Air ...

  8. 图解Spark Graphx实现顶点关联邻接顶点的函数原理

    一.场景案例 在一张社区网络里,可能需要查询出各个顶点邻接关联的顶点集合,类似查询某个人关系比较近的都有哪些人的场景. 在用Spark graphx中,通过函数collectNeighbors便可以获 ...

  9. 简单描述下HTTP协议和TCP协议之间的关系以及TCP三次握手, 四次挥手

    TCP 三次握手, 四次挥手 TCP(传输控制协议)是一种用于在计算机网络中建立可靠连接的协议.TCP连接的建立和终止分别使用了"三次握手"和"四次挥手"的过程 ...

  10. 图解 LeetCode 算法汇总——链表

    本文首发公众号:小码A梦 一般数据主要存储的形式主要有两种,一种是数组,一种是链表.数组是用来存储固定大小的同类型元素,存储在内存中是一片连续的空间.而链表就不同于数组.链表中的元素不是存储在内存中可 ...