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 mscreate 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 ms2、强制走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 msexplain (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 ms3、强制多条件组合
/*+ 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: 1Postgresql 定制执行计划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为代表的商业数据库,和 ...
随机推荐
- 【大数据面试】Hbase:数据、模型结构、操作、读写数据流程、集成、优化
一.概述 1.概念 分布式.可扩展.海量数据存储的NoSQL数据库 2.模型结构 (1)逻辑结构 store相当于某张表中的某个列族 (2)存储结构 (3)模型介绍 Name Space:相当于数据库 ...
- python基础语法&数据类型&运算符
1.标识符 # -*- coding:utf-8 -*- # @Time :2021/1/16 10:28 # @Author :QAbujiaban # @Email :wbxztoo@163.co ...
- BUU_RE学习记录
一.easyre 1.010打开,直接搜flag,得到flag 二.reverse1 1.先查壳,得知是64位无壳,直接用IDA打开 2.shiftF12查找字符串,发现关键语句 3.查看相应代码,F ...
- java中加号的用法
注意java中+号的使用 public class Add { public static void main(String[] args) { System.out.println(100+80); ...
- linux挖矿处置
挖矿的类型 主动挖矿:用户在个人电脑或服务器使用挖矿程序进行CPU,GPU计算,获取虚拟货币. 被动挖矿:挖矿病毒通过系统漏洞,恶意程序,弱口令等方式入侵服务器,设备感染挖矿病毒后会开始挖掘虚拟货币. ...
- LeetCode HOT 100:子集(简单易懂的回溯)
题目:78. 子集 题目描述: 给你一个整数数组,数组中元素互不相同.返回数组中所有可能的子集,且子集不能重复! 什么是子集?举个例子:原数组[1, 2, 3],[].[1].[1, 2].[1, 3 ...
- k3s安装kubernetes环境
官方文档:https://docs.rancher.cn/k3s/ 官方文档:https://rancher.com/docs/k3s/latest/en/installation/install-o ...
- Lombok介绍和配置
什么是Lombok Lombok是一个Java库,能自动插入编辑器并构建工具,简化Java开发. 官网: https://www.projectlombok.org/ Lombok的作用 通过 添加注 ...
- XCTF分站赛ACTF——Crypto
impossible RSA: 没啥好说的,跟我之前文章有道题类似,虽然如此还是花费了很长时间,原因令人落泪,把q = inverse(e,p)的数学式写成了eq mod p导致数学式推导及其困难(能 ...
- gitee删除上传到的远程分支的提交记录
在实际开发中可能也经常会遇到写完代码后提交到远程分支但发现写的提交信息有误,不符合规范.由于自己的gitee账号可能没有修改提交记录的权限.因此最佳的解决方法是,撤销本地分支当前的提交记录,将代码回滚 ...