PostgreSQL 语句调优_pgsqlwhere exists_疯狂小草的博客-程序员宅基地

技术标签: 调优  Postgre Sql  Sql  

PostgreSQL 语句调优-Sql语句优化


作为一名优秀的码农,对于了解Sql如何调优是很有必要的。。简单总结一下,
	
	1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引(单表索引不能超过六个)
	2.使用更多的条件,缩小查找范围
	3.使用关联时,用小结果集驱动大结果集

(ps:下面的语句推荐给司机们,赶快上车)
--EXPLAIN:表示打出某sql的执行计划,看看是否走了全表,ANALYZE: 表示需要消耗的时间耗时,
EXPLAIN ANALYZE SELECT id,a FROM A; 

下面是我日常用到的一些Sql优化点,大家可以借鉴一下

1. 查询字段优化 千万不要使用 SELECT * 用具体的字段列表替换 * ,不要返回用不到的字段

返回了不必有的数据,就会浪费内存,加重网络的负担降低性能 。如果表大,在表扫描的期间将表锁住,禁止其他的链接访问表,后果严重!!

--correct SQL
SELECT * FROM A; 
--error SQL
SELECT id FROM A WHERE create_time >'2019-1-1';
2. where子句 like调优

若在关键词abc前面用了“%”,会导致该Sql走全表查询,除非必要,否则不要在关键词前加%
ps: 查询耗时和字段值总长度成正比

--error SQL 
SELECT id FROM A WHERE name LIKE '%abc%';
--correct SQL
SELECT id FROM A WHERE name LIKE 'abc%';
3. where子句 避免对null做判断

该判断将导致引擎放弃使用索引而进行全表扫描,建议针对null字段设置默认值0

--error SQL 
SELECT id FROM A WHERE a ISNULL;
SELECT id FROM A WHERE a NOTNULL;
--correct SQL 可以在a上设置默认值0,确保表中a列没有null值
SELECT id FROM A WHERE a =0;
SELECT id FROM A WHERE a >0;
4. where子句 避免使用 != 或者 <>

该判断将导致引擎放弃使用索引而进行全表扫描,建议将不等于 拆成 大于或者小于

--error SQL 
SELECT id FROM A WHERE a !=2017;
--correct SQL 
SELECT id FROM A WHERE a >2017 OR a <2017;
5. where子句 避免使用 or

使用or的子句可以分解成多个查询,并且通过union链接多个查询。它们的速度只同是否使用索引有关,如果查询使用到联合索引,用unionAll执行的效率更高,多个or字段的字句没有用到索引,改写成union的形式,再视图与索引匹配

--error SQL 
SELECT id FROM A WHERE a >2017 OR a <2017;
--correct SQL 
SELECT id FROM A WHERE a >2017
UNION ALL
SELECT id FROM A WHERE a <2017;
6. where子句 避免使用 NOT IN 或者 IN

NOT IN sql执行时,会转成 <> 将导致引擎放弃使用索引而进行全表扫描,不推荐使用NOT IN
IN 也会使系统无法使用索引,而只能直接搜索表中的数据(ps:如果一定要使用in 注意在in后面值的列表中,将出现最频繁的值放在最前面,出现的最少的放在最后面,减少判断的次数)

--error SQL 
SELECT id FROM A WHERE a IN (2017,2018,2019);
SELECT id FROM A WHERE a IN (SELECT id FROM B);
--correct SQL  如果查询的是连续的值,可以使用BETWEEN AND 函数
SELECT id FROM A WHERE a BETWEEN 2017 AND 2019
--correct SQL  如果只是IN中的子表结果集比较大,建议使用 EXISTS
SELECT id FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id=a)
7. where子句 EXISTS 和 IN 的使用方式

IN 是在内存中比较的,只执行一次,把B表中的所有id字段缓存起来,之后检查A表的id是否与B表中的id相等,如果id相等则将A表的记录加入到结果集中,直到遍历完A表的所有记录
EXISTS 需要查询数据库,所以当B的数据量比较大时,EXISTS效率优于IN

--error SQL  
SELECT id FROM A WHERE a IN (SELECT id FROM B);
--correct SQL  
SELECT id FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id=a)
--correct SQL  如果只是IN子表查询结果,建议使用 EXISTS
SELECT id FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id=a)
8. where子句 避免在条件左侧使用算法

在where子句中的“=”左边进行函数、算数运算或其他表达式运算,系统可能无法正确的使用索引

--error SQL 
SELECT * FROM A WHERE a/2=100;
SELECT * FROM A WHERE SUBSTRING(a,1,4)=’6666’;
--correct SQL  
SELECT * FROM A WHERE a=100*2;
SELECT * FROM A WHERE a LIKE ’6666%’;
9. 避免使用 DISTINCT 和 ORDER BY

它会使查询变慢,这些动作可以改在客户端执行也可以

10. GROUP BY 和 HAVING 的优化

如果能在group by的having字句之前就能剔除多余的行,所以尽量不要用他们来做剔除行的动作。最优执行顺序:select 的where字句选择所有合适的行,group用来分组统计,having用于剔除多余的分组。这样group by和having的开销小,查询快。对于大的数据进行分组和having十分消耗资源。如果group by的目的不包括计算,只是分组。Distinct更快

11. INNER JOIN 比 LEFT JOIN和RIGHT JOIN快

因为inner join是等值连接,或许返回的行数比较少.提倡使用内联INNER JOIN

12. UNION ALL 比 UNION 快

UNION在进行表链接后会筛选掉重复的记录,UNION ALL不会去除重复记录
UNION将会按照字段的顺序进行排序,UNION ALL只是简单的将两个结果合并后就返回

13. 一次更新多条记录比分多次更新每次一条快

意思就是使用批处理更有效率

--error SQL 
INSERT INTO A(id,a) VALUES (1,10);
INSERT INTO A(id,a) VALUES (2,16);
--correct SQL  
INSERT INTO A(id,a) VALUES (1,10),(2,16);

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Jamel_LiToo/article/details/85332327

智能推荐

Win11用anaconda创建gym环境_anaconda 安装gym_一条小咸鱼~的博客-程序员宅基地

不了解虚拟环境的小伙伴可以看一下这个,可以对后续安装过程有一个理解,简而言之就是新创建一个容器来放第三方库,然后用这个虚拟环境的python解释器来运行代码。由于我运行的是其他的代码,期间出现了一系列的第三方库的版本不兼容的问题又或者是版本太高的问题,各位小伙伴如果遇到这种问题就逐一解决就可以啦(就是卸载、重装…你会发现C:\Windows\system32前面多了(gym),变成(gym)C:\Windows\system32,就是这样,然后安装一些组件((花了整整一天的时间,各种报错…_anaconda 安装gym

zzuli 1530_www.zz.1530_cddchina的博客-程序员宅基地

http://www.cnblogs.com/dengdai68/archive/2011/06/05/2073075.html_www.zz.1530

SNMP网管协议【网络管理协议】_.snmpv2支持管理站和管理站之间的通信-程序员宅基地

SNMP网管协议SNMP和CMIPSNMP(简单网络管理协议)和CMIP(通用管理信息协议)都是目前世界上最主要的两种网管协议。总的来说,SNMP和CMIP两种协议是相同点比较多。首先两者的管理目标和基本组成部分是相同的,由5个部分组成:被管设备,若干被管代理,至少一个网络管理器,一个公共网络管理协议,一种或多种管..._.snmpv2支持管理站和管理站之间的通信

【2023秋招面经】20220805安恒信息实习_饭啊饭°的博客-程序员宅基地

本系列主要整理博主2023秋招的面试情况。本节介绍20220805安恒信息实习。_安恒信息实习

谷歌、亚马逊的顶级GPU被质疑太贵了!这种CPU算法竟然快15倍_3D视觉工坊的博客-程序员宅基地

来源丨外媒、新智元编辑丨LZY赖斯大学的计算机科学家创造了一种替代GPU的方法,该算法使用通用中央处理器(CPU),并指出其训练深度神经网络(DNN) 的速度超过图形处理器平台(GPU)速...

【Altium Designer学习(四)】集成库的制作_制作集成库的大致流程-程序员宅基地

集成库即将原理图库和PCB库结合起来(当然还可能有其他的库),建立一种保护机制。下面即记录了如何建立一个集成库首先,File—New—Project—Integrated Library新建一个集成库然后再向其中添加原理图库和PCB模型库..._制作集成库的大致流程

随便推点

浅谈GC标记清除算法简述。串行GC,并行GC,CMS GC,G1 GC总结,这么多GC,该选择使用哪个GC?_cmsgc maxnewsize_ZhaoSimonone的博客-程序员宅基地

本文讲述了GC的标记算法,主要总结了串行GC,并行GC,CMS GC,G1 GC的主要特点已经相应的开启参数,提及了ZGC和Shenandoah GC。总结了上述GC的特点以及该如何选择GC。同时简单分析了GC中年轻代和老年代的大小分配。_cmsgc maxnewsize

Option 82在校园网的应用与实现(转)_weigetc的博客-程序员宅基地

作者:南京政治学院上海分院教育技术中心 陈晓晖经过近几年的建设,各高校大体完成了校园网基础环境建设,将建设重点逐步转移到信息资源与应用服务上,校园网的安全也越来越受重视,迫使网络管理员比以往更加需要在加强网络安全和便于使用之间找到一个平衡点。笔者认为在具备802.1x认证的硬件条件下,引入Option 82构建一个权限分配清晰的校园网是一项可行的措施。 DHCP Option 82说明和关键点

内存溢出和内存泄漏的区别_lxw1844912514的博客-程序员宅基地

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak..._18、内存溢出和内存泄漏

Kubernetes Ingress 报 504 Gateway Timeout 解决方案_ingress 504_LP_Cong的博客-程序员宅基地

记一次惨痛的调试经历在集群上件简单的新建一个命名空间,定一个Deployment,第一个Service,再定一个Ingress来外网访问。结果当外网访问的时候,一直报504 Gateway Timeout 的错误。一开始以为是Pods出了问题,结果随便进入一个容器,curl对应的Service发现一切正常,有返回。所以问题出在Ingress上。目测应该是Ingress无法访问Service的原因。所以推测应该是某些网络策略没有定义好。于是查K8S文档,发现这么一个文档。https.._ingress 504

Snipaste 截图工具_yilaguandemei的博客-程序员宅基地

snipaste 安装和使用(1)下载地址 :http://zh.snipaste.com/download.html 安装出现错误:snipaste api-ms-win-crt-runtime-l1-1-0.dll 错误 解决方法:https://www.microsoft.com/zh-CN/download/details.asp

Ubuntu 不小心升级内核/删除内核导致无法登陆图形界面,又错删显卡驱动补救过程_YANGN1的博客-程序员宅基地

(1)一开始说boot 没空间,然后图形界面没右边一栏。然后uninstall-gn sudo apt-get updatesudo apt-get install --reinstall ubuntu-desktopsudo apt-get install unity sudo service lightdm restart(2)进去了以后,又在home里删除了点东西 ,pytorch还...

推荐文章

热门文章

相关标签