今天同事给我一条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. MySQL到ClickHouse数据同步方案

    MySQL 同步到 ClickHouse的方案可以看下面的说明,选择合适最近的同步方法. 1. 对比结果概述 整体上,NineData(官网:www.ninedata.cloud )的数据复制功能在功 ...

  2. Sharding-Sphere使用HikariCP连接池连接Ojdbc6报Driver does not support get/set network timeout for connections. (oracle.jdbc.driver.T4CConnection.getNetworkTimeout()I)

    HikariCP连接Ojdbc6报错Driver does not support get/set network timeout for connections. (oracle.jdbc.driv ...

  3. PerfView 洞察C#托管堆内存 "黑洞现象"

    一:背景 1. 讲故事 首先声明的是这个 黑洞 是我定义的术语,它是用来表示 内存吞噬 的一种现象,何为 内存吞噬,我们来看一张图. 从上面的 卦象图 来看,GCHeap 的 Allocated=85 ...

  4. Django message组件

    使用message组件要在seetings中配置 ①INSTALLED_APPS   (项目需要什么功能都放在这 既可以有数据库,又可以写代码,html文件,和自己写的APP一个道理) ②MIDDLE ...

  5. KVM VM set net moel virtio and mulltiqueues

    check $ qemu-kvm -net nic,model=help qemu: Supported NIC models: ne2k_pci,i82551,i82557b,i82559er,rt ...

  6. 王道oj/problem12(动态申请内存存储数组)

    网址:http://oj.lgwenda.com/problem/12 思路:用输入的整型创建对应数组,用scanf消除换行键: 用gets()输入语句并输出,再释放. 代码: #define _CR ...

  7. koa搭建nodejs项目并注册接口

    使用nodejs注册接口逻辑处理会比较复杂,直接通过express或者koa能够简化开发流程,这里记录用koa来搭建nodejs项目并注册接口,对koa不太熟悉的话可以参考这一篇.让nodejs开启服 ...

  8. [故障处理]nfs导致系统负载异常

    目录 情况 排查 原因 解决 情况 某台虚拟机服务器系统负载极高,但是cpu.内存.IO都正常.home目录下无法使用ls,也无法使用 df -h. 排查 top看cpu和内存,正常. iotop看i ...

  9. [elasticsearch]部署安装单节点和集群

    单点安装 进入安装目录:cd /usr/local 获取安装包: wget http://172.29.50.31/download/ProgramPackage/elasticsearch/elas ...

  10. Mybatis框架的搭建和基本使用

    本文总结最原始Mybatis框架的搭建和最基本使用(不涉及Spring框架体系). 1 依赖 首先,我们要引入Mybatis依赖: <dependency> <groupId> ...