Postgresql 定制执行计划pg_hint_plan
一、概述
Plan Hint是PG社区官方版”永远”不考虑引入的功能之一,社区开发者的理念是,引入Hint功能,会掩盖优化器本身的问题,导致缺陷不被暴露出来。但对于使用者来讲,遇到某些SQL的查询计划不好,性能出了问题,其他方法又不奏效的情况下,首先的目标还是想尽快解决问题,而Hint就可以在这种时候帮助到我们。
二、配置
在postgresql.conf中修改shared_preload_libraries=‘pg_hint_plan'
三、示例
1、初始化测试数据
create
table
t1 (id
int
, t
int
,
name
varchar
(255));
create
table
t2 (id
int
, salary
int
);
create
table
t3 (id
int
, age
int
);
insert
into
t1
values
(1,200,
'jack'
);
insert
into
t1
values
(2,300,
'tom'
);
insert
into
t1
values
(3,400,
'john'
);
insert
into
t2
values
(1,40000);
insert
into
t2
values
(2,38000);
insert
into
t2
values
(3,18000);
insert
into
t3
values
(3,38);
insert
into
t3
values
(2,55);
insert
into
t3
values
(1,12);
explain analyze
select
*
from
t1
left
join
t2
on
t1.id=t2.id
left
join
t3
on
t1.id=t3.id;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Hash
Right
Join
(cost=89.82..337.92
rows
=17877 width=540) (actual
time
=0.053..0.059
rows
=3 loops=1)
Hash Cond: (t3.id = t1.id)
-> Seq Scan
on
t3 (cost=0.00..32.60
rows
=2260 width=8) (actual
time
=0.002..0.002
rows
=3 loops=1)
-> Hash (cost=70.05..70.05
rows
=1582 width=532) (actual
time
=0.042..0.043
rows
=3 loops=1)
Buckets: 2048 Batches: 1 Memory Usage: 17kB
-> Hash
Right
Join
(cost=13.15..70.05
rows
=1582 width=532) (actual
time
=0.034..0.039
rows
=3 loops=1)
Hash Cond: (t2.id = t1.id)
-> Seq Scan
on
t2 (cost=0.00..32.60
rows
=2260 width=8) (actual
time
=0.002..0.002
rows
=3 loops=1)
-> Hash (cost=11.40..11.40
rows
=140 width=524) (actual
time
=0.017..0.017
rows
=3 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan
on
t1 (cost=0.00..11.40
rows
=140 width=524) (actual
time
=0.010..0.011
rows
=3 loops=1)
Planning
time
: 0.154 ms
Execution
time
: 0.133 ms
create
index
idx_t1_id
on
t1(id);
create
index
idx_t2_id
on
t2(id);
create
index
idx_t3_id
on
t3(id);
explain analyze
select
*
from
t1
left
join
t2
on
t1.id=t2.id
left
join
t3
on
t1.id=t3.id;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Hash
Left
Join
(cost=2.14..3.25
rows
=3 width=540) (actual
time
=0.045..0.047
rows
=3 loops=1)
Hash Cond: (t1.id = t3.id)
-> Hash
Left
Join
(cost=1.07..2.14
rows
=3 width=532) (actual
time
=0.030..0.032
rows
=3 loops=1)
Hash Cond: (t1.id = t2.id)
-> Seq Scan
on
t1 (cost=0.00..1.03
rows
=3 width=524) (actual
time
=0.005..0.006
rows
=3 loops=1)
-> Hash (cost=1.03..1.03
rows
=3 width=8) (actual
time
=0.007..0.007
rows
=3 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan
on
t2 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.002..0.003
rows
=3 loops=1)
-> Hash (cost=1.03..1.03
rows
=3 width=8) (actual
time
=0.005..0.005
rows
=3 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan
on
t3 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.002..0.002
rows
=3 loops=1)
Planning
time
: 0.305 ms
Execution
time
: 0.128 ms
2、强制走Index
Scan
explain (analyze,buffers) /*+ indexscan(t1) */
select
*
from
t1
where
id=2;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Index
Scan using idx_t1_id
on
t1 (cost=0.13..8.15
rows
=1 width=524) (actual
time
=0.044..0.046
rows
=1 loops=1)
Index
Cond: (id = 2)
Buffers: shared hit=1
read
=1
Planning
time
: 0.145 ms
Execution
time
: 0.072 ms
explain (analyze,buffers) /*+ indexscan(t1 idx_t1_id) */
select
*
from
t1
where
id=2;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Index
Scan using idx_t1_id
on
t1 (cost=0.13..8.15
rows
=1 width=524) (actual
time
=0.016..0.017
rows
=1 loops=1)
Index
Cond: (id = 2)
Buffers: shared hit=2
Planning
time
: 0.079 ms
Execution
time
: 0.035 ms
3、强制多条件组合
/*+ indexscan(t2) indexscan(t1 idx_t1_id) */
/*+ seqscan(t2) indexscan(t1 idx_t1_id) */
explain analyze
SELECT
*
FROM
t1
JOIN
t2
ON
(t1.id = t2.id);
QUERY PLAN
--------------------------------------------------------------------------------------------------------
Hash
Join
(cost=1.07..2.14
rows
=3 width=532) (actual
time
=0.018..0.020
rows
=3 loops=1)
Hash Cond: (t1.id = t2.id)
-> Seq Scan
on
t1 (cost=0.00..1.03
rows
=3 width=524) (actual
time
=0.006..0.007
rows
=3 loops=1)
-> Hash (cost=1.03..1.03
rows
=3 width=8) (actual
time
=0.005..0.005
rows
=3 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan
on
t2 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.001..0.003
rows
=3 loops=1)
Planning
time
: 0.114 ms
Execution
time
: 0.055 ms
(8
rows
)
/*+ indexscan(t2) indexscan(t1 idx_t1_id) */explain analyze
SELECT
*
FROM
t1
JOIN
t2
ON
(t1.id = t2.id);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Merge
Join
(cost=0.26..24.40
rows
=3 width=532) (actual
time
=0.047..0.053
rows
=3 loops=1)
Merge Cond: (t1.id = t2.id)
->
Index
Scan using idx_t1_id
on
t1 (cost=0.13..12.18
rows
=3 width=524) (actual
time
=0.014..0.015
rows
=3 loops=1)
->
Index
Scan using idx_t2_id
on
t2 (cost=0.13..12.18
rows
=3 width=8) (actual
time
=0.026..0.028
rows
=3 loops=1)
/*+ seqscan(t2) indexscan(t1 idx_t1_id) */explain analyze
SELECT
*
FROM
t1
JOIN
t2
ON
(t1.id = t2.id);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.13..13.35
rows
=3 width=532) (actual
time
=0.025..0.032
rows
=3 loops=1)
Join
Filter: (t1.id = t2.id)
Rows
Removed
by
Join
Filter: 6
->
Index
Scan using idx_t1_id
on
t1 (cost=0.13..12.18
rows
=3 width=524) (actual
time
=0.016..0.018
rows
=3 loops=1)
-> Materialize (cost=0.00..1.04
rows
=3 width=8) (actual
time
=0.002..0.003
rows
=3 loops=3)
-> Seq Scan
on
t2 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.004..0.005
rows
=3 loops=1)
4、强制指定join method
/*+ NestLoop(t1 t2) MergeJoin(t1 t2 t3) Leading(t1 t2 t3) */
explain analyze
select
*
from
t1
left
join
t2
on
t1.id=t2.id
left
join
t3
on
t1.id=t3.id;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Merge
Left
Join
(cost=3.28..3.34
rows
=3 width=540) (actual
time
=0.093..0.096
rows
=3 loops=1)
Merge Cond: (t1.id = t3.id)
-> Sort (cost=2.23..2.23
rows
=3 width=532) (actual
time
=0.077..0.078
rows
=3 loops=1)
Sort
Key
: t1.id
Sort Method: quicksort Memory: 25kB
-> Nested Loop
Left
Join
(cost=0.00..2.20
rows
=3 width=532) (actual
time
=0.015..0.020
rows
=3 loops=1)
Join
Filter: (t1.id = t2.id)
Rows
Removed
by
Join
Filter: 6
-> Seq Scan
on
t1 (cost=0.00..1.03
rows
=3 width=524) (actual
time
=0.005..0.005
rows
=3 loops=1)
-> Materialize (cost=0.00..1.04
rows
=3 width=8) (actual
time
=0.002..0.003
rows
=3 loops=3)
-> Seq Scan
on
t2 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.002..0.003
rows
=3 loops=1)
-> Sort (cost=1.05..1.06
rows
=3 width=8) (actual
time
=0.012..0.013
rows
=3 loops=1)
Sort
Key
: t3.id
Sort Method: quicksort Memory: 25kB
-> Seq Scan
on
t3 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.002..0.003
rows
=3 loops=1)
/*+ NestLoop(t1 t2 t3) MergeJoin(t2 t3) Leading(t1 (t2 t3)) */
explain analyze
select
*
from
t1
left
join
t2
on
t1.id=t2.id
left
join
t3
on
t1.id=t3.id;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Nested Loop
Left
Join
(cost=1.07..3.31
rows
=3 width=540) (actual
time
=0.036..0.041
rows
=3 loops=1)
Join
Filter: (t1.id = t3.id)
Rows
Removed
by
Join
Filter: 6
-> Hash
Left
Join
(cost=1.07..2.14
rows
=3 width=532) (actual
time
=0.030..0.032
rows
=3 loops=1)
Hash Cond: (t1.id = t2.id)
-> Seq Scan
on
t1 (cost=0.00..1.03
rows
=3 width=524) (actual
time
=0.008..0.009
rows
=3 loops=1)
-> Hash (cost=1.03..1.03
rows
=3 width=8) (actual
time
=0.007..0.007
rows
=3 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan
on
t2 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.002..0.004
rows
=3 loops=1)
-> Materialize (cost=0.00..1.04
rows
=3 width=8) (actual
time
=0.001..0.002
rows
=3 loops=3)
-> Seq Scan
on
t3 (cost=0.00..1.03
rows
=3 width=8) (actual
time
=0.002..0.003
rows
=3 loops=1)
5、控制单条SQL的cost
/*+
set
(seq_page_cost 20.0) seqscan(t1) */
/*+
set
(seq_page_cost 20.0) seqscan(t1) */explain analyze
select
*
from
t1
where
id > 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Seq Scan
on
t1 (cost=0.00..20.04
rows
=1 width=524) (actual
time
=0.011..0.013
rows
=2 loops=1)
Filter: (id > 1)
Rows
Removed
by
Filter: 1
Postgresql 定制执行计划pg_hint_plan的更多相关文章
- PostgreSQL EXPLAIN执行计划学习--多表连接几种Join方式比较
转了一部分.稍后再修改. 三种多表Join的算法: 一. NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表 ...
- postgresql中执行计划
1.Explain explain select * from tablename; 2.explain输出josn格式 explain (format json) select * from tab ...
- PostgreSQL 修改执行计划 GroupAggregate 为 HashAggregate
1.前言 PostgreSQL 聚合算法有两种,HashAggregate and GroupAggregate .我们知道GroupAggregate 需要对记录进行排序,而 HashAggrega ...
- PostgreSQL 执行计划
简介 PostgreSQL是“世界上最先进的开源关系型数据库”.因为出现较晚,所以客户人群基数较MySQL少,但是发展势头很猛,最大优势是完全开源. MySQL是“世界上最流行的开源关系型数据库”.当 ...
- PostgreSQL执行计划:Bitmap scan VS index only scan
之前了解过postgresql的Bitmap scan,只是粗略地了解到是通过标记数据页面来实现数据检索的,执行计划中的的Bitmap scan一些细节并不十分清楚.这里借助一个执行计划来分析bitm ...
- PostgreSQL 与 Oracle 访问分区表执行计划差异
熟悉Oracle 的DBA都知道,Oracle 访问分区表时,对于没有提供分区条件的,也就是在无法使用分区剪枝情况下,优化器会根据全局的统计信息制定执行计划,该执行计划针对所有分区适用.在分析利弊之前 ...
- postgreSQL执行计划
" class="wiz-editor-body wiz-readonly" contenteditable="false"> explain命 ...
- PostgreSQL执行计划的解析
一个顺序磁盘页面操作的cost值由系统参数seq_page_cost (floating point)参数指定的,由于这个参数默认为1.0,所以我们可以认为一次顺序磁盘页面操作的cost值为1.下面o ...
- MySQL— 索引,视图,触发器,函数,存储过程,执行计划,慢日志,分页性能
一.索引,分页性能,执行计划,慢日志 (1)索引的种类,创建语句,名词补充(最左前缀匹配,覆盖索引,索引合并,局部索引等): import sys # http://www.cnblogs.com/w ...
- MySQL统计信息以及执行计划预估方式初探
数据库中的统计信息在不同(精确)程度上描述了表中数据的分布情况,执行计划通过统计信息获取符合查询条件的数据大小(行数),来指导执行计划的生成.在以Oracle和SQLServer为代表的商业数据库,和 ...
随机推荐
- Android ViewPager2 + TabLayout + BottomNavigationView
Android ViewPager2 + TabLayout + BottomNavigationView 实际案例 本篇主要介绍一下 ViewPager2 + TabLayout + BottomN ...
- 互联网最全cka真题解析-2022
1.CKA真题解析kubectl自动补全及帮助信息1.配置kubectl自动补全apt install bash-completion source <(kubectl completion b ...
- 解决SpringMVC重定向参数无法携带问题
解决SpringMVC重定向参数无法携带问题 场景 重定向时请求参数会丢失,我们往往需要重新携带请求参数,我们可以进⾏⼿动参数拼接如下: return "redirect:handle01? ...
- 第三篇:前端基础之JavaScript
前端基础之JavaScript JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaS ...
- [OpenCV实战]16 使用OpenCV实现多目标跟踪
目录 1 背景介绍 2 基于MultiTracker的多目标跟踪 2.1 创建单个对象跟踪器 2.2 读取视频的第一帧 2.3 在第一帧中确定我们跟踪的对象 2.4 初始化MultiTrackerer ...
- Rust-01 启航
安装 所谓工欲善其事必先利其器,我们学习Rust当然需要安装Rust.我们可以从Rust官网下载rustup工具进行rust的安装.安装完成后,我们在命令行中输入rustc --version便可以查 ...
- 【FAQ】推送服务常见问题及解决方案
一.推送成功收不到消息,推送返回:{"message":"success","requestID":"1523868*****28 ...
- C++string与int的相互转换(使用C++11)
一.int转string #include <iostream> #include <string> int main() { double f = 23.43; double ...
- Hugging Face 2023 实习生招募计划
Hugging Face 2023 实习生招募计划 想参与到 <王婆卖瓜>「最酷的 AI 社区」</王婆卖瓜>,共同构建未来吗?今天,我们为大家分享 Hugging Face ...
- .NET周报【1月第3期 2023-01-20】
这应该是2023年农历新年前的最后一篇.NET周报,再次预祝大家新年快乐! 国内文章 看我是如何用C#编写一个小于8KB的贪吃蛇游戏的 https://www.cnblogs.com/InCerry/ ...