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(物业管理系统),公司主要业务的是美国的租房业务.由于美国租房和中 ...
- JVM常用调优参数
目录 JVM内存模型及常用参数 参数解释 垃圾收集器 Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC) Parallel Scavenge收集器(-XX: ...
- Linux下“减速”查看日志的方法
Linux下"减速"查看日志的方法 需求场景 今天查看日志,有个需求,需要按照指定"速率"输出日志信息到终端屏幕上,方便查看. 这个需求日常应该也经常会碰到,比 ...
- CH579-Lwip-2.12移植
代码可以参考以下链接:https://gitee.com/maji19971221/lwip-routine Lwip可以在以下链接下载:http://download.savannah.gnu.or ...
- ssm——springMVC整理
目录 1.概念 1.1.什么是SpringMVC 1.2.B/S架构 1.3.MVC结构 1.4.Spring MVC常用名词 1.5.常用注解 1.6.rest和restfull 1.7.Reque ...
- [深度学习] CCPD车牌数据集介绍
CCPD是一个大型的.多样化的.经过仔细标注的中国城市车牌开源数据集.CCPD数据集主要分为CCPD2019数据集和CCPD2020(CCPD-Green)数据集.CCPD2019数据集车牌类型仅有普 ...
- [编程基础] C++多线程入门2-连接和分离线程
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 2 连接和 ...
- 一文详解RocketMQ的存储模型
摘要:RocketMQ 优异的性能表现,必然绕不开其优秀的存储模型. 本文分享自华为云社区<终于弄明白了 RocketMQ 的存储模型>,作者:勇哥java实战分享. RocketMQ 优 ...
- 低版本客户端连接高版本数据库报错ORA-28040、ORA-01017
测试环境: 客户端:Oracle 11.2.0.1 服务端:Oracle 19.16 测试过程: 1.低版本客户端连接高版本数据库报错ORA-28040 2.低版本客户端连接高版本数据库报错ORA-0 ...
- VUE Angular通用动态列表组件-亦可为自动轮播组件-02-根据数据量自动横向滚动,鼠标划入停止滚动
本文为横向轮播,纵向轮播/动态列表组件请戳---- 代码是angular的,稍微改改就可以放入Vue项目里,差别不大哟 以下代码可以根据实际情况自行调整 父组件html <app-scroll- ...