二月 5, 2024
摘要:pg_hint_plan
插件使 PostgreSQL 优化器能够针对指定查询强制执行某些决策,手动调整执行计划。
目录
概要
pg_hint_plan
可以通过在 SQL 注释中使用“提示”,比如/*+ SeqScan(a) */
,来调整 PostgreSQL 执行计划。
PostgreSQL 使用的是基于成本的优化器,它会利用数据统计信息,而不是静态规则。规划器(优化器)会估算 SQL 语句的每个可能的执行计划的成本,然后执行成本最低的执行计划。规划器会尽最大努力选择最佳执行计划,但并不总是完美的,因为它没有考虑某些数据属性或列之间的相关性。
描述
基本用法
给定一条 SQL 语句,pg_hint_plan
会读取其中特殊形式的注释中的提示短语。可以通过在提示前面加上序列前缀"/*+
",并以"*/
“结尾。提示短语由提示名称和参数组成,其中参数用括号括起来,并用空格分隔。提示短语可以使用换行符以提高可读性。
在下面的示例中,在对pgbench_accounts
执行顺序扫描时,选择了哈希连接作为连接方法:
=# /*+
HashJoin(a b)
SeqScan(a)
*/
EXPLAIN SELECT *
FROM pgbench_branches b
JOIN pgbench_accounts a ON b.bid = a.bid
ORDER BY a.aid;
QUERY PLAN
---------------------------------------------------------------------------------------
Sort (cost=31465.84..31715.84 rows=100000 width=197)
Sort Key: a.aid
-> Hash Join (cost=1.02..4016.02 rows=100000 width=197)
Hash Cond: (a.bid = b.bid)
-> Seq Scan on pgbench_accounts a (cost=0.00..2640.00 rows=100000 width=97)
-> Hash (cost=1.01..1.01 rows=1 width=100)
-> Seq Scan on pgbench_branches b (cost=0.00..1.01 rows=1 width=100)
(7 rows)
提示列表
下面列出了可用的提示。
分组 | 格式 | 描述 |
---|---|---|
扫描方式 | SeqScan(table) |
强制对表进行顺序扫描。 |
TidScan(table) |
强制对表进行 TID 扫描。 | |
IndexScan(table[ index...]) |
强制对表进行索引扫描。如果带有索引,则限制为指定的索引。 | |
IndexOnlyScan(table[ index...]) |
强制对表进行仅索引扫描。如果带有索引,则限制为指定的索引。如果仅索引扫描不可用,则可以使用索引扫描。 | |
BitmapScan(table[ index...]) |
强制对表进行位图扫描。如果带有索引,则限制为指定的索引。 | |
IndexScanRegexp(table[ POSIX Regexp...]) IndexOnlyScanRegexp(table[ POSIX Regexp...]) BitmapScanRegexp(table[ POSIX Regexp...]) |
强制对表进行索引扫描、仅索引扫描(适用于 PostgreSQL 9.2 及更高版本)或位图扫描。限制为与指定的 POSIX 正则表达式模式匹配的索引。 | |
NoSeqScan(table) |
强制不要对表进行顺序扫描。 | |
NoTidScan(table) |
强制不要对表进行 TID 扫描。 | |
NoIndexScan(table) |
强制不要对表执行索引扫描和仅索引扫描。 | |
NoIndexOnlyScan(table) |
强制不要对表执行仅索引扫描。 | |
NoBitmapScan(table) |
强制不要对表执行位图扫描。 | |
JOIN 方法 | NestLoop(table table[ table...]) |
强制对指定表的连接使用嵌套循环。 |
HashJoin(table table[ table...]) |
强制对指定表的连接使用哈希连接。 | |
MergeJoin(table table[ table...]) |
强制对指定表的连接使用合并连接。 | |
NoNestLoop(table table[ table...]) |
强制不要对指定表的连接使用嵌套循环。 | |
NoHashJoin(table table[ table...]) |
强制不要对指定表的连接使用哈希连接。 | |
NoMergeJoin(table table[ table...]) |
强制不要对指定表的连接使用合并连接。 | |
JOIN 顺序 | Leading(table table[ table...]) |
强制按指定的表顺序进行连接。 |
Leading(<join pair>) |
强制按指定的表顺序和连接方向进行连接。一个连接对是用括号括起来的一对表和/或其他连接对,这样可以构成一个嵌套结构。 | |
JOIN 时的行为控制 | Memoize(table table[ table...]) |
允许指定表之间连接时进行最顶层连接,以记住内部结果。不强制执行。 |
NoMemoize(table table[ table...]) |
禁止指定表之间连接时进行最顶层连接“记忆内部结果”。 | |
行数修正 | Rows(table table[ table...] correction) |
更正指定表上连接的结果的行数。可用的校正方法有绝对值(#)、加法(+)、减法(-) 和乘法(*)。它应该是 strtod() 可以理解的一个字符串。 |
并行查询配置 | Parallel(table <# of workers> [soft|hard]) |
强制或禁止对指定的表进行并行执行。<# of workers> 是所需的并行工作进程数,其中 0 表示禁止并行执行。如果第三个参数是 soft(默认值),则它只是更改max_parallel_workers_per_gather ,并将其他所有内容留给规划器。设置为 hard 强制使用指定数量的并行工作进程。 |
GUC | Set(GUC-param value) |
将 GUC 参数设置为规划器运行时定义的值。 |