PostgreSQL的查询提示(hint)扩展pg_hint_plan的使用

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介: 一条SQL语句采用哪个执行计划是由优化器根据代价估算自动选择的,但如果希望使用指定的执行计划,就需要进行干预。Oracle中通过提示(hint)干预特点SQL的执行计划,PostgreSQL本身也可以通过enable_bitmapscan之类的参数进行调节,但这些参数是针对会话的,对优化器的控制没有提示来的直接,也没有提示那么精细。

一条SQL语句采用哪个执行计划是由优化器根据代价估算自动选择的,但如果希望使用指定的执行计划,就需要进行干预。Oracle中通过提示(hint)干预特点SQL的执行计划,PostgreSQL本身也可以通过enable_bitmapscan之类的参数进行调节,但这些参数是针对会话的,对优化器的控制没有提示来的直接,也没有提示那么精细。
pg_hint_plan是2012年12月公开的一个开源PostgreSQL扩展,其作用于Oracle的Hint相同,并且使用方法也是一样的。下面演示一下pg_hint_plan的使用。

ge.jp/projects/pghintplan/)下载源码。
目前pg_hint_plan只支持PostgreSQL 9.1和9.2,这里使用的是9.2。

#tar xzf pg_hint_plan.tar.gz
#cd pg_hint_pla
#make USE_PGXS=1 PG_CONFIG=/usr/pgsql-9.2/bin/pg_config
#make USE_PGXS=1 PG_CONFIG=/usr/pgsql-9.2/bin/pg_config install


修改配置加载pg_hint_plan
#pg_ctl -D $PGDATA restart
#vi /pg_hba.conf
shared_preload_libraries = 'pg_hint_plan'

重启PG后就可以使用pg_hint_plan了
#pg_ctl -D $PGDATA restart


使用
postgres=# CREATE TABLE tbl(c1 int);
CREATE TABLE
postgres=# INSERT INTO tbl SELECT * from generate_series(1, 10);
INSERT 0 10
postgres=# CREATE INDEX idx ON tbl (c1);
CREATE INDEX
postgres=# VACUUM ANALYZE tbl;
VACUUM

由于记录少默认使用全表扫描。
postgres=# EXPLAIN SELECT * FROM tbl WHERE c1 = 1;
                    QUERY PLAN                    
---------------------------------------------------
 Seq Scan on tbl  (cost=0.00..1.12 rows=1 width=4)
   Filter: (c1 = 1)
(2 rows)


通过hint强制使用索引扫描
postgres=# /*+ IndexScan(tbl) */  EXPLAIN SELECT * FROM tbl WHERE c1 = 1;
                          QUERY PLAN                          
---------------------------------------------------------------
 Index Scan using idx on tbl  (cost=0.00..8.27 rows=1 width=4)
   Index Cond: (c1 = 1)
(2 rows)


pg_hint_plan支持很多提示语句,比如
扫描方式:
    SeqScan(table)
    TidScan(table)
    IndexScan(table[index])
    IndexOnlyScan(table[index])
    BitmapScan(table[index])

连接方式:                
    NestLoop(table table [table...])
    HashJoin(table table [table...])
    MergeJoin(table table [table...])

连接顺序:    
    Leading(table table [table...])

详细可参考pg_hint_plan源码doc目录中的手册

其他:
hint也不是万灵药,PostgreSQL社区的意见认为使用hint这样的机制干预优化器可能会带来维护麻烦,升级失效等一系列的问题。基于这样的考虑,估计PG社区将来也不准备把hint加入到PG本体中。相关讨论参见:http://wiki.postgresql.org/wiki/OptimizerHintsDiscussion

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
消息中间件 存储 关系型数据库
PostgreSQL技术大讲堂 - 第33讲:并行查询管理
PostgreSQL从小白到专家,技术大讲堂 - 第33讲:并行查询管理
503 1
|
9月前
|
存储 关系型数据库 数据库
postgresql|数据库|提升查询性能的物化视图解析
postgresql|数据库|提升查询性能的物化视图解析
893 0
|
3月前
|
SQL 关系型数据库 数据库
PostgreSQL性能飙升的秘密:这几个调优技巧让你的数据库查询速度翻倍!
【10月更文挑战第25天】本文介绍了几种有效提升 PostgreSQL 数据库查询效率的方法,包括索引优化、查询优化、配置优化和硬件优化。通过合理设计索引、编写高效 SQL 查询、调整配置参数和选择合适硬件,可以显著提高数据库性能。
738 1
|
5月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
6月前
|
缓存 关系型数据库 数据库
PostgreSQL 查询性能
【8月更文挑战第5天】PostgreSQL 查询性能
118 8
|
8月前
|
SQL 关系型数据库 数据库
Python执行PostgreSQL数据库查询语句,并打印查询结果
本文介绍了如何使用Python连接和查询PostgreSQL数据库。首先,确保安装了`psycopg2`库,然后创建数据库连接函数。接着,展示如何编写SQL查询并执行,例如从`employees`表中选取所有记录。此外,还讨论了处理查询结果、格式化输出和异常处理的方法。最后,提到了参数化查询和事务处理以增强安全性及确保数据一致性。
Python执行PostgreSQL数据库查询语句,并打印查询结果
|
7月前
|
Java 关系型数据库 API
使用Spring Boot和PostgreSQL构建高级查询
使用Spring Boot和PostgreSQL构建高级查询
|
关系型数据库 PostgreSQL
PostgreSQL pg_orphaned扩展
由于种种原因,PostgreSQL可能会产生一些孤儿文件,这些文件会占用磁盘空间,手工查找费时费力还容易出错,pg_orphaned扩展很好的解决了这个问题。
|
8月前
|
SQL 关系型数据库 数据库
Python查询PostgreSQL数据库
木头左教你如何用Python连接PostgreSQL数据库:安装`psycopg2`库,建立连接,执行SQL脚本如创建表、插入数据,同时掌握错误处理和事务管理。别忘了性能优化,利用索引、批量操作提升效率。下期更精彩!💡 csvfile
Python查询PostgreSQL数据库
|
9月前
|
SQL 人工智能 Oracle
PostgreSQL 递归查询(含层级和结构)
PostgreSQL 递归查询(含层级和结构)