网易首页 > 网易号 > 正文 申请入驻

PostgreSQL技术大讲堂 - 第31讲:SQL调优技巧

0
分享至

PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。

第31讲:SQL调优技巧

第31讲:10月28日(周六)19:30-20:30,往期文档及视频,联系CUUG

内容1 : SQL调优范式

内容2 : 多表查询调优技巧

内容3 : 多表查询应用案例

开发范式一

· 不要轻易把字段嵌入到表达式

在sal列上有索引,但是条件语句中把sal列放在了表达式当中,导致索引被压抑,因为索引里面储存的是sal列的值,而不是sal加上100以后的值。

testdb=# explain select * from emp2 where sal + 100 = 2000;

QUERY PLAN

Gather (cost=1000.00..7796.60 rows=2294 width=36)

Workers Planned: 2

-> Parallel Seq Scan on emp2 (cost=0.00..6567.20 rows=956 width=36)

Filter: ((sal + 100) = 2000)

(4 rows)

· 改写成

通过等式等换,把sal列从表达式中剥离出来,就会用到索引。

testdb=# explain select * from emp2 where sal = 2000 - 100;

QUERY PLAN

Index Scan using emp2_sal_ind on emp2 (cost=0.42..8.44 rows=1 width=36)

Index Cond: (sal = 1900)

(2 rows)

开发范式二

· 不要轻易把字段嵌入到函数中

在hiredate列上有索引,但是条件语句中把该列放在了函数当中,导致索引被压抑,因为索引里面储存的是该列的值,而不是函数处理以后的值。

testdb=# explain select * from emp2 where to_char(hiredate,'dd-mm-yyyy')='22-05-2022';

QUERY PLAN

Seq Scan on emp2 (cost=0.00..289.32 rows=50 width=62)

Filter: (to_char((hiredate)::timestamp with time zone, 'dd-mm-yyyy'::text) = '22-05-2022'::text)

· 改写成

通过等式转换,把列从函数中剥离出来,就会用到索引,比较成本,差别很大。

testdb=# explain select * from emp2 where hiredate=to_date('22-05-2022','dd-mm-yyyy');

QUERY PLAN

Index Scan using emp2_hiredate on emp2 (cost=0.29..8.30 rows=1 width=62)

Index Cond: (hiredate = to_date('22-05-2022'::text, 'dd-mm-yyyy'::text))

开发范式三

· 如果查询中比较固定查询某些列,可以基于这几个列建复合索引,直接查询索引,避开回表扫描。

create index emp2_empno on emp2 (empno,sal);

testdb=# explain select empno,sal from emp2 where empno=7788;

QUERY PLAN

Index Only Scan using emp2_empno on emp2 (cost=0.29..10.09 rows=2 width=8)

Index Cond: (empno = 7788)

多表查询指导方针

· OLTP应用SQL调优指导方针

-- 驱动表上有很好的条件限制,同时,驱动表上的限制性条件字段上应该有索引,包括主键、唯一索引或其它索引、复合索引等。

-- 在每次连接操作之后尽量保证返回记录数最少,传递给下一个连接操作。

-- 根据返回的行的数量对应正确的连接方式。

-- 尽量通过在被驱动表的连接字段上的索引,访问被驱动表。

-- 单表扫描应该有效率,如果被驱动表上还有其它限制条件,可以遵循复合索引创建原则,创建合适的复合索引(连接字段与条件字段)。

-- 全表扫描也许是合理的,例如若干小表、代码表的访问。

-- 依次类推,顺序完成所有表的连接操作。

· 多表连接调优总体思路

>> 如果是OLTP应用,则优化的思路是由小到大,即从限制性最强,返回记录最少的连接开始,依次完成其它表的连接,并在访问每张表时,合理使用索引,特别是复合索引技术。

>> 如果是OLAP应用,则优化思路基本是hash连接加并行处理,表连接顺序不是最主要的。

· 多表连接优化案例一

testdb=# explain select e.*,d.*

from emp e,dept d

where d.deptno=e.deptno

and e.empno=7499;

QUERY PLAN

Nested Loop (cost=0.30..16.36 rows=1 width=192)

-> Index Scan using pk_emp on emp e (cost=0.15..8.17 rows=1 width=98)

Index Cond: (empno = 7499)

-> Index Scan using pk_dept on dept d (cost=0.15..8.17 rows=1 width=94)

Index Cond: (deptno = e.deptno)

执行计划解读:

1、先按照建立在empno字段上的索引去emp表查询empno为7499的员工信息。

2、再根据7499所在的部门号(deptno)去dept表查询该部门的详细信息,而且dept表的deptno字段上应该有索引。

3、最后使用嵌套循环连接方式处理数据。

建议:

“如果是多表连接sql语句,注意驱动表的连接字段是否需要创建索引”。

在上例中,被驱动表是dept,dept表的连接字段是deptno,而emp的deptno字段是可以不需要建索引的,因为已经根据条件字段上列访问驱动表。

· 多表连接优化案例二

testdb=# explain select e.*,d.*

from emp e,dept d

where d.deptno=e.deptno

and e.empno=7499

and d.dname='DALLAS';

QUERY PLAN

Nested Loop (cost=0.30..20.35 rows=1 width=192)

-> Index Scan using pk_emp on emp e (cost=0.15..8.17 rows=1 width=98)

Index Cond: (empno = 7499)

-> Index Scan using pk_dept on dept d (cost=0.15..8.17 rows=1 width=94)

Index Cond: (deptno = e.deptno)

Filter: ((dname)::text = 'DALLAS'::text)

执行计划解读:

1、先按照建立在empno字段上的索引去emp表查询empno为7499的员工信息。

2、再根据7499所在的部门号(deptno)去dept表查询该部门的详细信息。此时dept表还有一个条件字段loc=‘DALLAS’,因此可考虑按(deptno,loc)复合索引方式去查询dept表,效率更高,即可建立(deptno,loc)字段上的复合索引(idx_dept_2)。

3、最后以嵌套循环的连接方式处理数据。

建议:

“如果是多表连接sql语句,注意是否可以在被驱动表的连接字段与该表的其它约束条件字段上创建复合索引”。索引可以在dept表上创建(deptno与dname)字段的复合索引。

执行计划解读(续)

应该遵循关于复合索引创建时的建议:

“如果单个字段是主键或者唯一字段,或者可选性非常高的字段,尽管约束条件字段比较固定,也不一定要建成复合索引,可建成单字段索引,降低复合索引开销”。

*而且通过比较发现这种情况创建单列索引比创建复合索引查询的时候代价要低的多。所以在本例中,不应该创建复合索引。

多表查询应用案例

· 5张查询应用案例

SELECT emp.last_name,emp.first_name,j.job_title,d.department_name,l.city,l.state_province,l.postal_code,l.street_address,emp.email,emp.phone_number,emp.hire_date,emp.salary,mgr.last_name

from hr.employees emp,hr.employees mgr,hr.departments d,hr.locations l,hr.jobs j

where l.city='South San Francisco'

and emp.manager_id=mgr.employee_id

and emp.department_id=d.department_id

and d.location_id=l.location_id

and emp.job_id=j.job_id;

· 第一种情况:无索引

在没有任何索引的情况下查看其执行计划 ,由于没有索引,所以所有扫描方式均为全表扫描,连接方式为hash join。

· 第二种情况:创建单列索引

在locations的city、location_id列上创建索引。

在departments的location_id上创建索引

在departments的department_id上创建主键约束

在employees的employee_id上创建主键约束

在jobs的job_id上创建主键约束。

· 第三种情况:创建复合索引

在locations的city、location_id列上创建复合索引。

在departments的department_id 、location_id上创建复合索引

在employees的employee_id、 department_id、manager_id、job_id上创建复合索引(或者单列索引)

在jobs的job_id上创建主键约束。

· 三种执行计划成本对比

经过分析发现,如果连接方式能够走嵌套循环,那么其成本比其它连接方式都低,当然我们要提供条件让优化器自动选择成本最低的连接方式,只要有一张表的访问方式是索引扫描,那么连接方式一般会选择嵌套循环。

Employees表的复合索引在执行计划中起到了作用,或者选择在连接条件列上( employee_id,department_id,manager_id )创建单列索引。

Departments和locations表的记录比较少,即使创建了单列或者多列索引,都不会使用索引。

连接顺序是L->D->EMP-MGR-J

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
端午节放假通知出来了,3个好消息,1个怀消息。

端午节放假通知出来了,3个好消息,1个怀消息。

华庭讲美食
2024-06-03 01:37:21
国家卫健委: 家长应关注孩子“远视储备量”,避免过早耗尽

国家卫健委: 家长应关注孩子“远视储备量”,避免过早耗尽

南方都市报
2024-05-31 22:06:15
海马斯暴击俄本土,俄希望的哈尔科夫缓冲区要建在自己家

海马斯暴击俄本土,俄希望的哈尔科夫缓冲区要建在自己家

移光幻影
2024-06-02 13:09:59
2025年世界五强位次将大洗牌?美国掉下首位,谁会是第一?

2025年世界五强位次将大洗牌?美国掉下首位,谁会是第一?

小蜜情感说
2024-06-02 22:24:33
台风“马力斯”跑偏了?明后两天强降雨确认,暴雨大暴雨分布如下

台风“马力斯”跑偏了?明后两天强降雨确认,暴雨大暴雨分布如下

冬天来旅游
2024-06-02 12:49:26
震撼!珠峰“大堵车”多人死亡,内幕简直令人头皮发麻 看完更畏惧

震撼!珠峰“大堵车”多人死亡,内幕简直令人头皮发麻 看完更畏惧

鬼谷子思维
2024-06-01 17:37:33
印媒挑拨:中华民族要伟大复兴,必须在2060年前打赢6场战争

印媒挑拨:中华民族要伟大复兴,必须在2060年前打赢6场战争

星辰大海路上的种花家
2024-06-01 13:43:06
国安核心离队后首次公开发声,就给了老东家下马威,让俱乐部难堪

国安核心离队后首次公开发声,就给了老东家下马威,让俱乐部难堪

罗掌柜体育
2024-06-02 18:25:16
雷军到深圳后海看小米大楼!楼高曝光,遭网友群嘲,理由出奇一致

雷军到深圳后海看小米大楼!楼高曝光,遭网友群嘲,理由出奇一致

开心体育站
2024-06-03 02:28:59
医院只认钱?浙江4岁男童被误诊,父亲花光60万,医院拒不退款

医院只认钱?浙江4岁男童被误诊,父亲花光60万,医院拒不退款

椰青美食分享
2024-06-02 21:00:27
太尴尬!汪小菲直播给儿子吃麻六记速食,儿子拆台吐槽:一股屎味

太尴尬!汪小菲直播给儿子吃麻六记速食,儿子拆台吐槽:一股屎味

山野下
2024-06-02 19:01:50
国防大学将军喊话泽连斯基:要考虑乌克兰人民的价值……

国防大学将军喊话泽连斯基:要考虑乌克兰人民的价值……

吃瓜体
2024-06-02 20:40:34
著名影星罗伯特·德尼罗在特朗普长篇大论后被剥夺了奖项

著名影星罗伯特·德尼罗在特朗普长篇大论后被剥夺了奖项

双旗镇叨客
2024-06-02 14:49:03
俄外长恼羞成怒,大骂瑞士抛弃中立 不配主办和平峰会

俄外长恼羞成怒,大骂瑞士抛弃中立 不配主办和平峰会

圈里的甜橙子
2024-06-03 02:00:23
居家自拍,压箱底的技术来了!

居家自拍,压箱底的技术来了!

花小猫的美食日常
2024-06-02 18:45:09
名校校长的"后宫":88名女教师,霸占87人?!

名校校长的"后宫":88名女教师,霸占87人?!

北国向锡安
2024-05-11 09:55:37
聊天时,把“在干嘛”换成这几句话,一准撩得女人春心荡漾!

聊天时,把“在干嘛”换成这几句话,一准撩得女人春心荡漾!

户外阿崭
2024-06-03 00:40:08
创造历史!张志磊第五回合KO维尔德,重拳轰倒对手,高喊中国力量

创造历史!张志磊第五回合KO维尔德,重拳轰倒对手,高喊中国力量

体坛扒客
2024-06-02 08:50:54
温柔如你,美丽动人。红颜知己,倾国倾城。

温柔如你,美丽动人。红颜知己,倾国倾城。

花小猫的美食日常
2024-06-02 21:32:20
央视“台花”刘芳菲情路坎坷,丈夫冤死,如今暴瘦到认不出。

央视“台花”刘芳菲情路坎坷,丈夫冤死,如今暴瘦到认不出。

阿芒娱乐说
2024-06-02 23:30:13
2024-06-03 05:42:44
CUUG
CUUG
北京神脑资讯技术有限公司
467文章数 20关注度
往期回顾 全部

科技要闻

黄仁勋:2026年将推下代GPU架构平台Rubin

头条要闻

女子称穿7cm厚洞洞鞋下楼时崴脚摔倒 左腿粉碎性骨折

头条要闻

女子称穿7cm厚洞洞鞋下楼时崴脚摔倒 左腿粉碎性骨折

体育要闻

从0-1到2-1!石宇奇绝地反击逆转队友李诗沣,豪夺赛季第3冠

娱乐要闻

白玉兰提名:胡歌、范伟争视帝

财经要闻

新造车5月销量: 小鹏乏力 问界暂"缺席"

汽车要闻

吉利银河E5 Flyme Auto智能座舱首发

态度原创

教育
时尚
本地
健康
军事航空

教育要闻

TTS新传论文带读:中国互联网30年!一篇文章就给整明白!!!

涂山“红红”现身戛纳?

本地新闻

食味印象|歙县限定!枇杷味儿的清甜初夏

晚餐不吃or吃七分饱,哪种更减肥?

军事要闻

美国中央司令部称拦截胡塞武装射向美军舰的导弹

无障碍浏览 进入关怀版