今天同事给我一条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. PlayWright(二十)- Pytest之conftest文件

    1.介绍与使用场景 conftest.py 这个是什么呢?   顾名思义,他就是一个文件,那这个文件是干什么用的呢?   在我们上文中,用了fixture函数是直接在用例的文件里定义的,那不能我们所有 ...

  2. Windows商店开发者注册失败

    前言 最近写了个小工具想上架Windows应用商店,但是在填写信息那一页总是失败,提示Error code 2201. Correlation ID 9d436e3a-94df-498a-b224-8 ...

  3. Django: 获取头信息

    如何获取请求头信息 使用如下函数request.META.get("HTTP_请求头函数"),需要注意的是,请求头变量需要全部大写. 其他注意事项如下所示: 如果headerkey ...

  4. Tcpdump 使用指南

    论网络数据包的分析,我首选wireshark,因为图形化界面直观明了.但如果遇到没有图形化显示的Linux环境,那么此时会使用tcpdump该是一件多么美好的事情. 网上关于tcpdump的介绍很多, ...

  5. [mysql]MGR简介与部署

    前言 MySQL Group Replication,简称MGR,是MySQL官方于2016年推出的一个全新的高可用解决方案,采用Paxos分布式一致性协议作为高可用和一致性解决方案.在MGR之前的高 ...

  6. 【技术积累】Linux中的命令行【理论篇】【九】

    blkid命令 命令介绍 blkid命令是一个用于查看块设备属性的Linux命令.它可以识别和显示块设备的文件系统类型.UUID.LABEL.PARTUUID等信息. 命令说明 在Linux下可以使用 ...

  7. docker-compose快速部署elasticsearch-8.x集群+kibana

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<Docker下elasticse ...

  8. Android-JAR包的引用

    一.JAR的定义     JAR文件(Java归档,英语:Java Archive)是一种软件包文件格式,以ZIP格式构建,以.jar为文件扩展名,通常用于聚合大量的Java类文件.相关的元数据和资源 ...

  9. Git-更换服务器问题

    一.Permission denied (publickey) git指令出现Permission denied (publickey),是ssh key过期的问题,需要对ssh key进行更新,所有 ...

  10. shopee商品详情接口的应用

    Shopee是东南亚和台湾地区最大的电子商务平台之一,成立于2015年,目前覆盖6个国家和地区.作为一家新兴电商平台,Shopee拥有快速增长的销售额和庞大的用户群体,为开发者提供了丰富的商业机会.其 ...