Postgresql 中文操作指南

32.2. When to JIT? #

JIT 编译主要对长时间运行的 CPU 密集型查询有益。通常情况下,这些查询都是分析性查询。对于短查询,执行 JIT 编译所增加的开销通常比节省的时间要更大。

为了确定是否应使用 JIT 编译,会使用查询的总估计开销(请参阅 Chapter 76Section 20.7.2)。查询的估计开销将与 jit_above_cost 的设置进行比较。如果开销较高,将执行 JIT 编译。然后需要做出另外两个决定。首先,如果估计开销高于 jit_inline_above_cost 的设置,将在查询中使用的短函数和运算符进行内联。其次,如果估计开销高于 jit_optimize_above_cost 的设置,将应用昂贵的优化来改进生成的代码。这些选项每个都会增加 JIT 编译开销,但可以大幅缩短查询执行时间。

这些基于成本的决策将在计划时间做出,而不是执行时间。这意味着,当使用预准备语句时,且使用通用计划(请参阅 PREPARE ),准备时间有效的配置参数的值控制决策,而不是执行时间的设置。

Note

如果 jit设置为_off_,或者如果没有任何 JIT 实现(例如,因为服务器是在没有_—​with-llvm_的情况下编译的),则不会执行 JIT,即使根据上述标准,执行 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_costjit_optimize_above_cost 也被降低,那将发生变化。