一、参数作用范围
1. 会话级参数(Session-level)
-- 只影响当前会话/连接
SET enable_seqscan = off; -- 当前会话生效
-- 在事务中,使用 SET LOCAL 只影响当前事务
BEGIN;
SET LOCAL enable_seqscan = off;
-- ... 执行查询 ...
COMMIT; -- 事务结束后恢复原设置
2. 数据库级参数
-- 影响整个数据库(需要超级用户)
ALTER DATABASE your_db_name SET enable_seqscan = off;
-- 查看数据库特定设置
SELECT datname, setconfig
FROM pg_database
WHERE datname = 'your_db_name';
3. 用户级参数
-- 影响特定用户的所有会话
ALTER USER your_username SET enable_seqscan = off;
-- 查看用户特定设置
SELECT usename, useconfig
FROM pg_user
WHERE usename = 'your_username';
4. 全局参数
-- 修改 postgresql.conf 并重启
-- 或者使用 ALTER SYSTEM(需要超级用户)
ALTER SYSTEM SET enable_seqscan = off;
SELECT pg_reload_conf(); -- 重载配置,部分参数立即生效
二、主要执行计划控制参数
扫描方法控制
| 参数 |
默认值 |
功能描述 |
全局/会话 |
enable_seqscan |
on |
启用顺序扫描(全表扫描) |
会话级 |
enable_indexscan |
on |
启用索引扫描 |
会话级 |
enable_indexonlyscan |
on |
启用仅索引扫描 |
会话级 |
enable_bitmapscan |
on |
启用位图扫描 |
会话级 |
enable_tidscan |
on |
启用TID扫描(按行号) |
会话级 |
连接方法控制
| 参数 |
默认值 |
功能描述 |
全局/会话 |
enable_nestloop |
on |
启用嵌套循环连接 |
会话级 |
enable_mergejoin |
on |
启用合并连接 |
会话级 |
enable_hashjoin |
on |
启用哈希连接 |
会话级 |
其他计划控制
| 参数 |
默认值 |
功能描述 |
全局/会话 |
enable_sort |
on |
启用显式排序 |
会话级 |
enable_material |
on |
启用物化 |
会话级 |
enable_incremental_sort |
on |
启用增量排序 |
会话级 |
enable_gathermerge |
on |
启用聚集合并 |
会话级 |
enable_partitionwise_join |
on |
启用分区智能连接 |
会话级 |
enable_partitionwise_aggregate |
on |
启用分区智能聚合 |
会话级 |
enable_parallel_append |
on |
启用并行追加 |
会话级 |
enable_parallel_hash |
on |
启用并行哈希 |
会话级 |
并行查询控制
| 参数 |
默认值 |
功能描述 |
全局/会话 |
max_parallel_workers_per_gather |
2 |
每个Gather节点的最大并行工作进程数 |
会话级 |
max_parallel_workers |
8 |
系统最大并行工作进程数 |
全局级 |
parallel_leader_participation |
on |
并行查询中leader进程是否参与工作 |
会话级 |
enable_partition_pruning |
on |
启用分区裁剪 |
会话级 |
三、详细功能说明
1. 扫描方法参数
-- 禁用全表扫描,强制使用索引
SET enable_seqscan = off;
EXPLAIN SELECT * FROM users WHERE age > 30;
-- 禁用索引扫描,强制全表扫描
SET enable_indexscan = off;
SET enable_bitmapscan = off;
EXPLAIN SELECT * FROM users WHERE age > 30;
-- 仅索引扫描(覆盖索引)
SET enable_indexonlyscan = off;
EXPLAIN SELECT id FROM users WHERE id > 100; -- 使用覆盖索引
2. 连接方法参数
-- 强制使用嵌套循环连接(适合小表驱动)
SET enable_hashjoin = off;
SET enable_mergejoin = off;
SET enable_nestloop = on;
EXPLAIN SELECT * FROM small_table s JOIN large_table l ON s.id = l.id;
-- 强制使用哈希连接(适合无索引的大表连接)
SET enable_nestloop = off;
SET enable_mergejoin = off;
SET enable_hashjoin = on;
EXPLAIN SELECT * FROM table1 JOIN table2 ON table1.id = table2.id;
-- 强制使用合并连接(适合已排序的数据)
SET enable_nestloop = off;
SET enable_hashjoin = off;
SET enable_mergejoin = on;
EXPLAIN SELECT * FROM table1 JOIN table2 ON table1.id = table2.id;
3. 排序和物化参数
-- 禁用显式排序(可能导致哈希连接使用更多内存)
SET enable_sort = off;
EXPLAIN SELECT * FROM users ORDER BY name;
-- 禁用物化(可能影响子查询性能)
SET enable_material = off;
EXPLAIN SELECT * FROM (SELECT * FROM users WHERE age > 30) AS subquery;
4. 并行查询参数
-- 增加并行度
SET max_parallel_workers_per_gather = 4;
SET max_parallel_workers = 16;
-- 禁用并行查询
SET max_parallel_workers_per_gather = 0;
SET enable_parallel_hash = off;
-- leader进程不参与工作(释放更多CPU)
SET parallel_leader_participation = off;
四、代价参数调整(影响优化器选择)
重要代价参数
| 参数 |
默认值 |
功能描述 |
推荐调整场景 |
seq_page_cost |
1.0 |
顺序扫描读取一页的代价 |
SSD盘可调低 |
random_page_cost |
4.0 |
随机读取一页的代价 |
SSD盘可调低至1.1-1.5 |
cpu_tuple_cost |
0.01 |
处理一个元组的CPU代价 |
CPU密集型查询 |
cpu_index_tuple_cost |
0.005 |
处理一个索引元组的CPU代价 |
索引扫描优化 |
cpu_operator_cost |
0.0025 |
执行一个操作的CPU代价 |
复杂表达式 |
effective_cache_size |
4GB |
估计可用于缓存的磁盘页数 |
根据实际内存调整 |
调整示例
-- 针对SSD优化(随机读代价降低)
SET random_page_cost = 1.1;
SET seq_page_cost = 1.0;
-- 针对内存数据库优化
SET random_page_cost = 1.0;
SET seq_page_cost = 1.0;
SET effective_cache_size = '8GB';
-- 鼓励使用索引(降低索引扫描代价)
SET cpu_index_tuple_cost = 0.0025;
SET random_page_cost = 2.0; -- 相对提高随机读代价
五、查看当前参数设置
1. 查看所有参数
-- 查看所有参数及其来源
SELECT name, setting, unit, source, sourcefile, sourceline
FROM pg_settings
WHERE name LIKE 'enable_%'
OR name LIKE '%cost%'
OR name LIKE 'max_parallel%'
ORDER BY name;
-- 查看会话级设置
SELECT name, setting, pending_restart
FROM pg_settings
WHERE source = 'session'; -- 会话级修改
2. 查看参数作用域
-- 查看参数上下文(决定在哪里设置)
SELECT name, context, vartype, min_val, max_val
FROM pg_settings
WHERE name IN (
'enable_seqscan', 'enable_indexscan',
'random_page_cost', 'work_mem'
);
-- context 含义:
-- postmaster: 需要重启
-- sighup: 需要重新加载配置
-- backend: 每个后端可以单独设置
-- user: 用户可随时修改
-- superuser: 需要超级用户权限
-- internal: 只读参数