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为代表的商业数据库,和 ...
随机推荐
- 如何使用Abstract类?抽象类的威力
简介: 今天我想谈谈如何使用抽象类,以及抽象类真正的威力.本文将结合具体业务来说明如何使用抽象类. 业务简述: 本人目前只接触过PMS(物业管理系统),公司主要业务的是美国的租房业务.由于美国租房和中 ...
- JavaScript:七大基础数据类型:数值number及其表示范围
数值number类型,用来表示任何类型的数字:整数或者浮点数都可以: 实际上,JS中的数值,是一个64位的浮点数,这与Java中的double类型的浮点数是一致的: 但是它有表示的范围,在范围内,JS ...
- 从Babel开始认识AST抽象语法树
前言 AST抽象语法树想必大家都有听过这个概念,但是不是只停留在听过这个层面呢.其实它对于编程来讲是一个非常重要的概念,当然也包括前端,在很多地方都能看见AST抽象语法树的影子,其中不乏有vue.re ...
- Web初级——模块和Bom
模块导入 导出声明 定义时声明 在定义声明函数.类时不用加分号 // 导出数组 export let months = ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep' ...
- Linux C 用GPS时间更新系统时间的方法。
思路: 1.GPS模块会自动收到带时间信息的消息. GPS模块会收到很多的协议消息带时间信息的.我们选择"$GPRMC"这条协议.其中的时间格式有的是hhmmss(时分秒) 有的是 ...
- Ubuntu snap 下载慢
解决方法 sudo apt-get install snapd sudo snap install snap-store sudo snap install snap-store-proxy sudo ...
- Docker 基础 - 1
镜像 获取镜像 docker pull 查看镜像信息 docker images docker inspect <images id> # 获取镜像的详细信息 搜寻镜像 docker se ...
- SOFAJRaft源码阅读-Netty时间轮算法的实践
SOFAJRaft的定时任务调度器是基于Netty来实现的,所以本文将会基于Netty时间轮算法,然后再结合SOFAJRaft源码进行分析. @Author:Akai-yuan @更新时间:2023/ ...
- 重学c#系列—— IO流[三十四]
前言 简单介绍一下io流. 以前写过两篇,里面是java 语言写的,简单介绍了一下io流,这里是对io流的整理. https://www.cnblogs.com/aoximin/p/12007925. ...
- TS不能将类型“any[]”分配给类型“never[]”
一.问题 在处理接口返回的数据,赋值给store中的数组时,报类型错误 data:{ cateList: [] } const getCateList = async () => { const ...