JIT 编译主要对运行时间长的 CPU 绑定查询有益。这些查询通常是分析查询。对于短查询,执行 JIT 编译带来的额外开销通常会高于它可以节省的时间。
要确定是否应使用 JIT 编译,将使用查询的总估计成本(请参阅 第 76 章 和 第 20.7.2 节)。查询的估计成本将与 jit_above_cost 的设置进行比较。如果成本较高,将执行 JIT 编译。然后需要再做出两个决定。首先,如果估计成本高于 jit_inline_above_cost 的设置,将在查询中使用的短函数和运算符内联。其次,如果估计成本高于 jit_optimize_above_cost 的设置,将应用昂贵的优化来改进生成的代码。这些选项中的每一个都会增加 JIT 编译开销,但可以显著减少查询执行时间。
这些基于成本的决策将在计划时间做出,而不是执行时间。这意味着当准备好的语句正在使用时,并且使用通用计划(参见PREPARE),准备时间生效的配置参数值控制决策,而不是执行时间的设置。
如果jit设置为off
,或者如果没有可用的JIT实现(例如,因为服务器是在没有--with-llvm
的情况下编译的),即使基于上述标准是有益的,也不会执行JIT。将jit设置为off
在计划时间和执行时间都有影响。
EXPLAIN可用于查看是否使用了JIT。作为一个示例,这里有一个不使用JIT的查询
=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class; QUERY PLAN ------------------------------------------------------------------------------------------------------------- Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1) -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1) Planning Time: 0.116 ms Execution Time: 0.365 ms (4 rows)
鉴于计划的成本,完全合理的是没有使用JIT;JIT的成本将大于潜在的节省。调整成本限制将导致使用JIT
=# SET jit_above_cost = 10; SET =# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class; QUERY PLAN ------------------------------------------------------------------------------------------------------------- Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1) -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1) Planning Time: 0.133 ms JIT: Functions: 3 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 1.259 ms, Inlining 0.000 ms, Optimization 0.797 ms, Emission 5.048 ms, Total 7.104 ms Execution Time: 7.416 ms
如这里所示,使用了JIT,但没有使用内联和昂贵的优化。如果jit_inline_above_cost或jit_optimize_above_cost也降低了,那将发生改变。