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为代表的商业数据库,和 ...
随机推荐
- Vue GET xxxx/sockjs-node/info?t=1573626343344 net::ERR_CONNECTION
看了很多资料,都说是关闭热更新要么注释掉代码完美解决.我寻思这不就没有热更新功能了吗. 不妨试试检查下项目端口是否一致,然后查看下请求地址是否是本地地址.有可能是因为被shadowsocket代理了 ...
- k3s安装kubernetes环境
官方文档:https://docs.rancher.cn/k3s/ 官方文档:https://rancher.com/docs/k3s/latest/en/installation/install-o ...
- 【转载】github.com访问慢解决办法
打开网站 IPAddress.com ,找到页面中下方的"IP Address Tools – Quick Links" 分别输入github.global.ssl.fastly. ...
- 记录Typescript的学习调试笔记(比 javascript更具面向对象,强类型检查,静态字段,适合现代的大团队分工与管理风格).
1.)先来一段Typescript的环境安装. 安装nodejs ,下载地址:https://nodejs.org/en/download/ //(node-v12.1 ...
- Js生成图片验证码
上代码 /** * [使用说明] * 1.生成验证码 * 函数: * generateRandomCode( dom对象Id ); * 例: * generateRandomCode( 'id' ); ...
- DVWA靶场实战(六)——Insecure CAPTCHA
DVWA靶场实战(六) 六.Insecure CAPTCHA: 1.漏洞原理: Insecure CAPTCHA(不安全的验证码),CAPTCHA全程为Completely Automated Pub ...
- 《STL源码剖析》STL迭代器分类
input迭代器:只能向前移动,一次一步,用户只能读取,不能修改它们所指向的东西,而且只能读取一次. output迭代器情况类似,但一切只为输出:它们只能向前移动,一次一步,用户只可以修改它们所指向的 ...
- 8. 字符串转整数 (atoi)
题目 代码 class Solution { public: int myAtoi(string str) { int res=0,sign=1; int i=str.find_first_not_o ...
- VUE Angular通用动态列表组件-亦可为自动轮播组件-01-根据数据量自动纵向滚动,鼠标划入停止滚动
本文为纵向轮播,横向轮播/动态列表组件请戳---- 代码是angular的,稍微改改就可以放入Vue项目里,差别不大哟 以下代码可以根据实际情况自行调整 父组件html <app-scroll- ...
- 【随笔记】Android 命令行联网、更新DNS、同步网络时间
一.命令行联网 # 启用网卡 busybox ifconfig wlan0 up # 启用服务 wpa_supplicant -iwlan0 -Dnl80211 -c/system/etc/wifi/ ...