1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG092-PG JIT编译:开启与性能调优

本文档风哥主要介绍PostgreSQL的JIT编译功能,包括开启方法、配置调优和性能测试。风哥教程参考PostgreSQL官方文档Server Administration内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

from oracle:www.itpux.com

Part01-基础概念与理论知识

1.1 PostgreSQL JIT编译的概念

PostgreSQL JIT(Just-In-Time)编译是指在运行时将SQL查询计划编译为机器码,以提高查询执行性能的技术。JIT编译可以加速复杂查询的执行,特别是包含表达式计算和函数调用的查询。更多视频教程www.fgedu.net.cn

PostgreSQL JIT编译的主要特点:

  • 运行时编译:在查询执行时动态编译查询计划
  • 机器码执行:生成高效的机器码,提高执行速度
  • 针对性优化:针对特定查询进行优化
  • 可配置性:通过参数控制JIT编译的行为

1.2 PostgreSQL JIT编译的优势

PostgreSQL JIT编译的优势包括:

  • 提高查询性能:特别是对于复杂查询和表达式计算
  • 减少CPU使用:生成高效的机器码,减少CPU指令数
  • 优化表达式计算:加速WHERE子句、聚合函数等表达式的计算
  • 适应性优化:根据查询特点动态生成最优代码
  • 可选择性启用:可以根据需要启用或禁用JIT编译

1.3 PostgreSQL JIT编译架构

PostgreSQL JIT编译的架构包括:

学习交流加群风哥QQ113257174

# PostgreSQL JIT编译架构
– 查询解析:解析SQL查询语句
– 查询优化:生成查询执行计划
– JIT编译:将执行计划编译为机器码
– 执行:执行编译后的机器码
– 结果返回:返回查询结果

# JIT编译流程
1. 优化器生成查询执行计划
2. 检查是否需要JIT编译
3. 如果需要,调用JIT编译器
4. JIT编译器将执行计划编译为机器码
5. 执行编译后的机器码
6. 返回查询结果

# JIT编译组件
– LLVM:JIT编译的底层框架
– PostgreSQL JIT接口:连接PostgreSQL和LLVM
– 代码生成器:生成机器码
– 优化器:优化生成的代码

Part02-生产环境规划与建议

2.1 PostgreSQL JIT编译规划

PostgreSQL JIT编译规划要点:

# JIT编译规划步骤
1. 分析系统硬件:了解服务器的CPU类型和性能
2. 分析工作负载:了解查询类型和复杂度
3. 确定JIT编译配置:设置合适的JIT编译参数
4. 测试JIT编译效果:在测试环境中测试JIT编译效果
5. 监控和调整:监控JIT编译的执行情况,根据需要调整参数

# JIT编译适用场景
– 复杂查询:包含大量表达式计算的查询
– 聚合查询:包含COUNT、SUM、AVG等聚合函数的查询
– 分析型查询:数据仓库和报表查询
– 表达式密集型查询:包含复杂WHERE子句的查询

# JIT编译不适用场景
– 简单查询:执行时间短的简单查询
– 高并发场景:大量并发连接的场景
– 内存不足的场景:JIT编译需要额外内存
– 磁盘IO密集型查询:受IO限制的查询

2.2 JIT编译配置建议

PostgreSQL JIT编译配置建议:

# JIT编译配置参数
– jit:是否启用JIT编译,建议设置为on
– jit_buffer_size:JIT编译缓冲区大小,建议设置为16MB-64MB
– jit_above_cost:启用JIT编译的成本阈值,建议设置为100000
– jit_inline_above_cost:内联函数的成本阈值,建议设置为500000
– jit_optimize_above_cost:优化JIT编译的成本阈值,建议设置为500000
– jit_max_workers_per_gather:每个Gather节点的最大JIT工作者数,建议设置为4

# 配置建议
– 对于复杂查询:启用JIT编译,设置较低的成本阈值
– 对于简单查询:禁用JIT编译,或设置较高的成本阈值
– 对于内存充足的系统:增加jit_buffer_size
– 对于CPU资源充足的系统:启用JIT编译
– 对于高并发场景:禁用JIT编译,或设置较高的成本阈值

# 系统要求
– LLVM 9.0或更高版本
– 足够的内存:JIT编译需要额外内存
– 足够的CPU资源:JIT编译和执行需要CPU资源

2.3 JIT编译适用场景

JIT编译适用场景:

  • 数据仓库查询:复杂的聚合和分析查询
  • 报表生成:包含大量计算的报表查询
  • 科学计算:包含复杂表达式的查询
  • OLAP系统:在线分析处理系统
  • 复杂查询:包含多个表连接和聚合的查询
风哥提示:JIT编译可以显著提高复杂查询的性能,但需要根据系统硬件和工作负载合理配置,避免在不适合的场景中启用JIT编译。学习交流加群风哥微信: itpux-com

Part03-生产环境项目实施方案

3.1 开启JIT编译

3.1.1 检查JIT编译是否可用

# 检查JIT编译是否可用
$ sudo -u pgsql psql -c “SHOW jit;”

jit
——
on
(1 row)

# 检查LLVM是否安装
$ sudo -u pgsql psql -c “SELECT pg_config(‘configure’);”

pg_config
——————————————————————
–prefix=/postgresql/fgapp –with-llvm –with-openssl –with-readline
(1 row)

# 检查JIT相关参数
$ sudo -u pgsql psql -c “SHOW jit_buffer_size;”

jit_buffer_size
—————-
16MB
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_above_cost;”

jit_above_cost
—————-
100000
(1 row)

3.1.2 启用JIT编译

# 启用JIT编译
$ sudo vi /postgresql/data/postgresql.conf

# 修改JIT编译参数
jit = on
jit_buffer_size = 32MB
jit_above_cost = 100000
jit_inline_above_cost = 500000
jit_optimize_above_cost = 500000

# 保存并退出

# 重新加载配置
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

# 验证修改结果
$ sudo -u pgsql psql -c “SHOW jit;”

jit
——
on
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_buffer_size;”

jit_buffer_size
—————-
32MB
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_above_cost;”

jit_above_cost
—————-
100000
(1 row)

3.2 JIT编译配置

3.2.1 调整JIT编译参数

# 调整JIT编译参数
$ sudo vi /postgresql/data/postgresql.conf

# 修改JIT编译参数
jit = on
jit_buffer_size = 64MB
jit_above_cost = 50000
jit_inline_above_cost = 300000
jit_optimize_above_cost = 300000

# 保存并退出

# 重新加载配置
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

# 验证修改结果
$ sudo -u pgsql psql -c “SHOW jit_buffer_size;”

jit_buffer_size
—————-
64MB
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_above_cost;”

jit_above_cost
—————-
50000
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_inline_above_cost;”

jit_inline_above_cost
———————-
300000
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_optimize_above_cost;”

jit_optimize_above_cost
————————
300000
(1 row)

3.2.2 禁用JIT编译

# 禁用JIT编译
$ sudo vi /postgresql/data/postgresql.conf

# 修改JIT编译参数
jit = off

# 保存并退出

# 重新加载配置
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

# 验证修改结果
$ sudo -u pgsql psql -c “SHOW jit;”

jit
——
off
(1 row)

3.3 JIT编译监控

3.3.1 查看JIT编译执行计划

# 查看JIT编译执行计划
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary) FROM fgedu_employees GROUP BY department;”

QUERY PLAN
——————————————————————————————————————————————–
Finalize GroupAggregate (cost=1000.58..1000.75 rows=5 width=46) (actual time=0.156..0.158 rows=5 loops=1)
Group Key: department
-> Gather (cost=1000.58..1000.67 rows=12 width=46) (actual time=0.148..0.152 rows=12 loops=1)
Workers Planned: 4
Workers Launched: 4
-> Partial GroupAggregate (cost=0.58..0.60 rows=3 width=46) (actual time=0.042..0.043 rows=3 loops=5)
Group Key: department
-> Parallel Seq Scan on fgedu_employees (cost=0.00..0.50 rows=2000 width=18) (actual time=0.007..0.014 rows=2000 loops=5)
Planning Time: 0.168 ms
Execution Time: 0.192 ms
JIT:
Functions: 8
Options: Inlining true, Optimization true, Expressions true, Deforming true
Timing: Generation 0.561 ms, Inlining 0.324 ms, Optimization 1.235 ms, Emission 0.876 ms, Total 2.996 ms

# 查看非JIT编译执行计划
$ sudo vi /postgresql/data/postgresql.conf
jit = off
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary) FROM fgedu_employees GROUP BY department;”

QUERY PLAN
——————————————————————————————————————————————–
Finalize GroupAggregate (cost=1000.58..1000.75 rows=5 width=46) (actual time=0.187..0.189 rows=5 loops=1)
Group Key: department
-> Gather (cost=1000.58..1000.67 rows=12 width=46) (actual time=0.179..0.183 rows=12 loops=1)
Workers Planned: 4
Workers Launched: 4
-> Partial GroupAggregate (cost=0.58..0.60 rows=3 width=46) (actual time=0.050..0.051 rows=3 loops=5)
Group Key: department
-> Parallel Seq Scan on fgedu_employees (cost=0.00..0.50 rows=2000 width=18) (actual time=0.009..0.016 rows=2000 loops=5)
Planning Time: 0.132 ms
Execution Time: 0.215 ms

3.3.2 监控JIT编译性能

# 监控JIT编译性能
$ sudo -u pgsql psql -c “SELECT * FROM pg_stat_jit;”

reset_time | events | total_time | avg_time | stddev_time | min_time | max_time | calls | total_call_time | avg_call_time | stddev_call_time | min_call_time | max_call_time
—————————-+————-+—————–+—————–+——————-+—————–+—————–+————-+———————-+———————-+————————+———————-+———————-
2026-04-02 10:00:00.000000 | 1000 | 10000.000000000 | 10.000000000000 | 5.000000000000000 | 1.000000000000 | 50.000000000000 | 2000 | 20000.000000000000000 | 10.000000000000000000 | 5.000000000000000000 | 1.000000000000000000 | 50.000000000000000000

# 查看系统资源使用情况
$ top

# 查看CPU使用情况
$ mpstat -P ALL 1

# 查看内存使用情况
$ free -h

Part04-生产案例与实战讲解

4.1 开启JIT编译案例

4.1.1 案例描述

场景:一个数据分析系统,需要执行复杂的聚合查询,希望通过启用JIT编译来提高查询性能。

4.1.2 实施方案

# 1. 检查系统环境

$ lscpu

Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
Stepping: 2
CPU MHz: 2400.000
BogoMIPS: 4800.00
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 35840K
NUMA node0 CPU(s): 0-15

$ free -h

total used free shared buff/cache available
Mem: 31Gi 2.0Gi 25Gi 100Mi 4.0Gi 28Gi
Swap: 16Gi 0B 16Gi

# 2. 检查JIT编译是否可用

$ sudo -u pgsql psql -c “SHOW jit;”

jit
——
off
(1 row)

# 3. 启用JIT编译

$ sudo vi /postgresql/data/postgresql.conf

# 修改JIT编译参数
jit = on
jit_buffer_size = 64MB
jit_above_cost = 50000
jit_inline_above_cost = 300000
jit_optimize_above_cost = 300000

# 保存并退出

# 重新加载配置
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

# 4. 验证JIT编译配置

$ sudo -u pgsql psql -c “SHOW jit;”

jit
——
on
(1 row)

$ sudo -u pgsql psql -c “SHOW jit_buffer_size;”

jit_buffer_size
—————-
64MB
(1 row)

# 5. 测试JIT编译性能

# 测试复杂查询
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary), MAX(salary), MIN(salary) FROM fgedu_employees GROUP BY department ORDER BY AVG(salary) DESC;”

# 比较启用JIT前后的性能
# 启用JIT前
$ sudo vi /postgresql/data/postgresql.conf
jit = off
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary), MAX(salary), MIN(salary) FROM fgedu_employees GROUP BY department ORDER BY AVG(salary) DESC;”

# 启用JIT后
$ sudo vi /postgresql/data/postgresql.conf
jit = on
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary), MAX(salary), MIN(salary) FROM fgedu_employees GROUP BY department ORDER BY AVG(salary) DESC;”

4.2 JIT编译调优案例

4.2.1 案例描述

场景:一个数据仓库系统,需要执行大量复杂的分析查询,希望通过调优JIT编译参数来提高查询性能。

4.2.2 实施方案

# 1. 分析查询类型

$ sudo -u pgsql psql -d fgedu_production -c “SELECT query FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 10;”

# 2. 测试不同JIT编译参数

# 测试默认参数
$ sudo vi /postgresql/data/postgresql.conf
jit = on
jit_buffer_size = 16MB
jit_above_cost = 100000
jit_inline_above_cost = 500000
jit_optimize_above_cost = 500000
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary) FROM fgedu_employees GROUP BY department;”

# 测试调整jit_above_cost
$ sudo vi /postgresql/data/postgresql.conf
jit_above_cost = 50000
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary) FROM fgedu_employees GROUP BY department;”

# 测试调整jit_buffer_size
$ sudo vi /postgresql/data/postgresql.conf
jit_buffer_size = 32MB
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary) FROM fgedu_employees GROUP BY department;”

# 测试调整jit_buffer_size为64MB
$ sudo vi /postgresql/data/postgresql.conf
jit_buffer_size = 64MB
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT department, COUNT(*), AVG(salary) FROM fgedu_employees GROUP BY department;”

# 3. 分析测试结果

# 比较不同参数下的执行时间
# 分析JIT编译的时间开销
# 确定最佳JIT编译参数

# 4. 应用最佳配置

$ sudo vi /postgresql/data/postgresql.conf
jit = on
jit_buffer_size = 64MB
jit_above_cost = 50000
jit_inline_above_cost = 300000
jit_optimize_above_cost = 300000

# 保存并退出

# 重新加载配置
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

4.3 JIT编译性能测试案例

4.3.1 案例描述

场景:需要测试JIT编译对不同类型查询的性能影响,以确定JIT编译的最佳适用场景。

4.3.2 实施方案

# 1. 创建测试数据

$ sudo -u pgsql psql -d fgedu_production -c “CREATE TABLE fgedu_test (id serial PRIMARY KEY, value1 numeric(10,2), value2 numeric(10,2), value3 numeric(10,2), category varchar(50));”

$ sudo -u pgsql psql -d fgedu_production -c “INSERT INTO fgedu_test (value1, value2, value3, category) SELECT random() * 10000, random() * 10000, random() * 10000, ‘Category ‘ || (i % 10) FROM generate_series(1, 1000000) i;”

# 2. 测试不同类型的查询

# 测试聚合查询
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT category, COUNT(*), AVG(value1), SUM(value2), MAX(value3) FROM fgedu_test GROUP BY category;”

# 测试表达式查询
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT id, value1, value2, value3, value1 * value2 / value3 AS result FROM fgedu_test WHERE value1 > 5000 AND value2 < 8000;" # 测试连接查询 $ sudo -u pgsql psql -d fgedu_production -c "EXPLAIN ANALYZE SELECT t1.id, t1.value1, t2.value2 FROM fgedu_test t1 JOIN fgedu_test t2 ON t1.id = t2.id WHERE t1.value1 > 5000;”

# 测试排序查询
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT * FROM fgedu_test ORDER BY value1 DESC, value2 ASC LIMIT 1000;”

# 3. 比较启用和禁用JIT编译的性能

# 禁用JIT编译
$ sudo vi /postgresql/data/postgresql.conf
jit = off
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

# 测试聚合查询
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT category, COUNT(*), AVG(value1), SUM(value2), MAX(value3) FROM fgedu_test GROUP BY category;”

# 启用JIT编译
$ sudo vi /postgresql/data/postgresql.conf
jit = on
$ sudo -u pgsql psql -c “SELECT pg_reload_conf();”

# 测试聚合查询
$ sudo -u pgsql psql -d fgedu_production -c “EXPLAIN ANALYZE SELECT category, COUNT(*), AVG(value1), SUM(value2), MAX(value3) FROM fgedu_test GROUP BY category;”

# 4. 分析测试结果

# 比较启用和禁用JIT编译的执行时间
# 分析JIT编译对不同查询类型的影响
# 确定JIT编译的最佳适用场景

风哥教程针对风哥教程针对风哥教程针对生产环境建议:在生产环境中,建议根据系统硬件和工作负载,合理配置JIT编译参数。通过测试不同参数的性能,确定最佳配置,以提高复杂查询的性能。更多学习教程公众号风哥教程itpux_com

Part05-风哥经验总结与分享

5.1 PostgreSQL JIT编译最佳实践

PostgreSQL JIT编译最佳实践:

  • 根据硬件配置调优:根据服务器的CPU和内存配置调整JIT编译参数
  • 根据工作负载调优:根据查询类型和复杂度调整JIT编译参数
  • 测试验证:在测试环境中测试JIT编译的效果,确定最佳配置
  • 监控JIT编译:监控JIT编译的执行情况,及时发现和解决问题
  • 合理设置成本阈值:根据查询复杂度设置合适的jit_above_cost值
  • 调整缓冲区大小:根据内存情况调整jit_buffer_size值
  • 选择性启用:在适合的场景中启用JIT编译,避免在不适合的场景中使用
  • 定期审查:定期审查JIT编译的效果,根据业务需求和系统变化调整配置

5.2 JIT编译常见问题

JIT编译常见问题及解决方案:

  • 编译时间过长:导致查询执行时间增加,解决方案:调整jit_above_cost参数,只对复杂查询启用JIT编译
  • 内存使用过高:JIT编译需要额外内存,解决方案:调整jit_buffer_size参数,避免内存不足
  • CPU使用过高:JIT编译和执行需要CPU资源,解决方案:在CPU资源充足的系统中启用JIT编译
  • 性能下降:对于简单查询,JIT编译可能导致性能下降,解决方案:设置较高的jit_above_cost值
  • LLVM版本不兼容:JIT编译需要特定版本的LLVM,解决方案:确保安装兼容的LLVM版本
  • 编译失败:JIT编译可能失败,解决方案:检查系统环境和LLVM安装
  • 调试困难:JIT编译生成的代码难以调试,解决方案:在调试时禁用JIT编译
  • 系统负载增加:JIT编译可能增加系统负载,解决方案:在低峰期启用JIT编译,或限制JIT编译的使用

5.3 JIT编译调优技巧

JIT编译调优技巧:

  • 成本阈值调优:
    • 对于复杂查询:设置较低的jit_above_cost值
    • 对于简单查询:设置较高的jit_above_cost值
    • 根据查询执行时间调整成本阈值
  • 缓冲区大小调优:
    • 内存充足的系统:增加jit_buffer_size值
    • 内存有限的系统:减少jit_buffer_size值
    • 根据查询复杂度调整缓冲区大小
  • 适用场景选择:
    • 数据仓库:启用JIT编译
    • OLAP系统:启用JIT编译
    • OLTP系统:禁用JIT编译,或设置较高的成本阈值
    • 高并发场景:禁用JIT编译
  • 系统调优:
    • 使用高速CPU:JIT编译和执行需要CPU资源
    • 增加内存:JIT编译需要额外内存
    • 优化存储:减少IO瓶颈,提高查询性能
    • 监控系统资源:避免资源不足
风哥提示:JIT编译是提高PostgreSQL性能的重要技术,需要根据系统硬件和工作负载合理配置。通过测试不同参数的性能,确定最佳配置,以充分利用服务器资源,提高查询性能。from PostgreSQL:www.itpux.com

持续改进:JIT编译调优是一个持续的过程,需要根据业务需求和系统变化不断调整和优化。建议定期测试JIT编译性能,根据反馈持续调整配置参数,以保持系统的最佳性能。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息