今天同事给我一条2秒的SQL看看能不能优化。

原始SQL:

SELECT pk_dept
FROM aaaa
WHERE 1 = 1
AND ((pk_group = '0001A110000000000JQ6' AND pk_org IN ('0001A110000000001M09')))
AND (PK_DEPT IN (SELECT t1.ORGID
FROM xxxxx t1
INNER JOIN (SELECT (CASE WHEN ORGID3 IS NULL THEN ORGID2 ELSE ORGID3 END) orgid
FROM xxxxx
WHERE ORGID = '1001A110000000001U8S') t2
ON t1.ORGID2 = t2.orgid OR t1.ORGID3 = t2.orgid))
AND (enablestate IN (2))
ORDER BY code;
4 loops=1)
Heap Fetches: 0
Planning Time: 258.024 ms
Execution Time: 2493.882 ms
(1583 rows)

xxxxx   表是一张非常复杂的视图,上面SQL执行计划大概2千行左右,所以本案例就不放整体的计划了。

如果经常做优化的同学对于简单的SQL,相信可以使用瞪眼大法基本定位到语句慢的位置

子查询慢SQL:

  SELECT t1.ORGID
FROM xxxxx t1
INNER JOIN (SELECT (CASE WHEN ORGID3 IS NULL THEN ORGID2 ELSE ORGID3 END) orgid
FROM xxxxx
WHERE ORGID = '1001A110000000001U8S') t2
ON t1.ORGID2 = t2.orgid OR t1.ORGID3 = t2.orgid

主要是慢在连接列的 OR 关系运算符上。

我们可以仔细看看这条SQL,xxxxx 分别作为t1、t2 表内连接关联2次, 关联条件为:t1.ORGID2 = t2.orgid OR t1.ORGID3 = t2.orgid

这种关联条件的逻辑关系可以简化为: t1.ORGID2 = t1.ORGID3

SQL语句可以进行以下精简:

SELECT t1.ORGID FROM xxxxx t1 where  ORGID = '1001A110000000001U8S';

验证等价逻辑:

ncc=#   SELECT t1.ORGID
ncc=# FROM xxxxx t1
ncc=# INNER JOIN
ncc=# (SELECT (CASE WHEN ORGID3 IS NULL THEN ORGID2 ELSE ORGID3 END) orgid FROM xxxxx
ncc=# WHERE ORGID = '1001A110000000001U8S') t2
ncc=# ON t1.ORGID2 = t2.orgid OR t1.ORGID3 = t2.orgid;
orgid
----------------------
1001A110000000001U8S
(1 row) ncc=# SELECT t1.ORGID FROM xxxxx t1 where ORGID = '1001A110000000001U8S';
orgid
----------------------
1001A110000000001U8S
(1 row) ncc=#

可以看到子查询SQL进行改写后是结果是等价的,使用逻辑公式进行化繁为简。

改写优化SQL后执行计划:

SELECT pk_dept
FROM org_dept
WHERE 1 = 1
AND ((pk_group = '0001A110000000000JQ6' AND pk_org IN ('0001A110000000001M09')))
AND (PK_DEPT IN (SELECT t1.ORGID
FROM EHR_ORG_DEPT t1
where ORGID = '1001A110000000001U8S')
)
AND (enablestate IN (2))
ORDER BY code;
                                                                                 ->  Seq Scan on org_dept d1_35  (cost=0.00..639.33 rows=7133 width=116) (actual time=0.047..1.480 rows=7133 loops=1)
-> Hash (cost=120.64..120.64 rows=3224 width=21) (actual time=1.315..1.315 rows=3224 loops=1)
Buckets: 4096 Batches: 1 Memory Usage: 199kB
-> Index Only Scan using pk_bd_region on bd_region bg_35 (cost=0.28..120.64 rows=3224 width=21) (actual time=0.024..0.651 rows=3224 loops=1)
Heap Fetches: 0
Planning Time: 86.684 ms
Execution Time: 625.439 ms

2.4秒的SQL最后通过化繁为简最终优化到625毫秒就能跑出结果。

总结:逻辑思维课程还是挺重要的,建议大家有空的时候去看看。

教你使用逻辑公式和恒等式等价改写SQL的更多相关文章

  1. Lambda表达式Contains方法(等价于SQL语句中的like)使用注意事项

    貌似已经半年多没写一篇帖子了,充分的说明要么老总一天折腾的让人心齐疲惫,没心情去写:要么另外一种可能就是自己不思进取,说白了就是懒.好在这种状态在今天被打破了.MoNey加油. 众所周知,想在Enti ...

  2. 逻辑很重要:一句sql语句的事,自己却想了半天,绕了个大弯子

    问题:系统升级后审核认证信息分别写入两个表,现在需要链接用户表和相应的新旧审核表获取字段值? 钻进胡同里:一直纠结于升级之后的会员信息从新表查,升级之前的数据从旧表查,纠结于根据时间戳分条件判断, 其 ...

  3. MySQL(逻辑分层,存储引擎,sql优化,索引优化以及底层实现(B+Tree))

    一 , 逻辑分层 连接层:连接与线程处理,这一层并不是MySQL独有,一般的基于C/S架构的都有类似组件,比如连接处理.授权认证.安全等. 服务层:包括缓存查询.解析器.优化器,这一部分是MySQL核 ...

  4. Postgresql_根据执行计划优化SQL

    执行计划路径选择 postgresql查询规划过程中,查询请求的不同执行方案是通过建立不同的路径来表达的,在生成许多符合条件的路径之后,要从中选择出代价最小的路径,把它转化为一个计划,传递给执行器执行 ...

  5. oracle里的查询转换

    oracle里的查询转换的作用 Oracle里的查询转换,有称为查询改写,指oracle在执行目标sql时可能会做等价改写,目的是为了更高效的执行目标sql 在10g及其以后的版本中,oracle会对 ...

  6. 朱世杰恒等式的应用-以CF841C为例

    题目大意 Codeforces 841C Leha and Function. 令\(F(n,k)\)为在集合\(\{x|x \in [1,n]\}\)中选择一个大小为k的子集,最小元素的期望值. 给 ...

  7. 详细分析SQL语句逻辑执行过程和相关语法

    本文目录: 1.SQL语句的逻辑处理顺序 1.2 各数据库系统的语句逻辑处理顺序 1.2.1 SQL Server和Oracle的逻辑执行顺序 1.2.2 MariaDB的逻辑执行顺序 1.2.3 M ...

  8. bzoj 3944 杜教筛

    题目中要求phi和miu的前缀和,利用杜教筛可以推出公式.我们令为 那么有公式 类比欧拉函数,我们可以推出莫比乌斯函数的和公式为  (公式证明懒得写了,主要核心是利用Dirichlet卷积的性质 ph ...

  9. MySql数据查询的逻辑蕴含条件问题

    SQL语言中没有蕴含逻辑运算.但是,可以利用谓词演算将一个逻辑蕴含的谓词等价转换为:p->q ≡┐p∨q. 我们通过一个具体的题目来分析:(具体的表和数据详见文章:Mysql数据库中的EXIST ...

  10. [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛)

    [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛) 题面 我们知道,从区间\([L,R]\)(L和R为整数)中选取N个整数,总共有\((R-L+1)^N\)种方案.求最大公约数 ...

随机推荐

  1. Go语言的Printf用法

    在 Go 语言中,Printf 是用于格式化输出的函数,用于将数据以指定格式打印到标准输出或其他输出流.其中,%p 是 Printf 函数的一个格式化动词,用于输出指针的值. 以下是 %p 的详细说明 ...

  2. spring-mvc系列:简介和基本使用

    目录 一.简介 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.基本使用 1.开发环境 2.创建maven工程 3.配置web.xml 4.创建SpringMVC的配 ...

  3. Codeforces 1850H:The Third Letter 带权并查集

    1850H.The Third Letter Description: \(n\) 个人,\(m\) 个条件,每次给出两个人 \(a_i\) 和 \(b_i\) 一维的位置关系,以距离 \(d_i\) ...

  4. 《深入理解Java虚拟机》读书笔记:HotSpot虚拟机对象探秘

    基于实用优先的原则,以常用的虚拟机HotSpot和常用的内存区域Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程.以下是本节内容的脑图. HotSpot虚拟机对象 ...

  5. 从redis未授权访问到获取服务器权限

    从redis未授权访问到获取服务器权限 好久没写博客了,博客园快荒芜了.赶紧再写一篇,算是一个关于自己学习的简要的记录把. 这里是关于redis未授权访问漏洞的一篇漏洞利用: 首先是redis,靶场搭 ...

  6. vlak

    2023-7-14 题目 luogu题目传送门 题目描述 Nina 和 Emilija 正在玩一个特殊的游戏.这个游戏是在一张最开始为空白的纸上进行的.在每一个人的行动回合内,这个人会在这张纸上当前的 ...

  7. OpenSSH版本升级漏洞修复问题

    Hi, I'm @Merbelue 大家好,这篇为大家介绍二进制方式对OpenSSH版本升级,在生产环境中可用于解决版本升级.漏洞修复等. @ 目录 1.环境 2.安装telnet 2.1.检查是否安 ...

  8. 详细讲解js实现电梯导航

    场景 对于某一个页面内容繁多, 如果我们滚动的时间较长,为了增加用户体验. 我们需要实现点击某一个按钮,然后滚动到对应的区域. 滚动的时候,右侧对应的分类实现高亮 其实,这个功能就2个步骤: 1.点击 ...

  9. 地表最帅缓存Caffeine

    简介 缓存是程序员们绕不开的话题,像是常用的本地缓存Guava,分布式缓存Redis等,是提供高性能服务的基础.今天敬姐带大家一起认识一个更高效的本地缓存--Caffeine. Caffeine Ca ...

  10. LeetCode297:hard级别中最简单的存在,java版,用时击败98%,内存击败百分之九十九

    本篇概览 因为欣宸个人水平有限,在刷题时一直不敢面对hard级别的题目,生怕出现一杯茶一包烟,一道hard做一天的窘境 这种恐惧心理一直在,直到遇见了它:LeetCode297,建议不敢做hard题的 ...