Postgresql 中文操作指南

32.2. When to JIT? #

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

JIT compilation is beneficial primarily for long-running CPU-bound queries. Frequently these will be analytical queries. For short queries the added overhead of performing JIT compilation will often be higher than the time it can save.

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

To determine whether JIT compilation should be used, the total estimated cost of a query (see Chapter 76 and Section 20.7.2) is used. The estimated cost of the query will be compared with the setting of jit_above_cost. If the cost is higher, JIT compilation will be performed. Two further decisions are then needed. Firstly, if the estimated cost is more than the setting of jit_inline_above_cost, short functions and operators used in the query will be inlined. Secondly, if the estimated cost is more than the setting of jit_optimize_above_cost, expensive optimizations are applied to improve the generated code. Each of these options increases the JIT compilation overhead, but can reduce query execution time considerably.

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

These cost-based decisions will be made at plan time, not execution time. This means that when prepared statements are in use, and a generic plan is used (see PREPARE), the values of the configuration parameters in effect at prepare time control the decisions, not the settings at execution time.

Note

如果 jit设置为_off_,或者如果没有任何 JIT 实现(例如,因为服务器是在没有_—​with-llvm_的情况下编译的),则不会执行 JIT,即使根据上述标准,执行 JIT 会有益。将 jit设置为_off_在计划和执行时间都会产生影响。

If jit is set to off, or if no JIT implementation is available (for example because the server was compiled without —​with-llvm), JIT will not be performed, even if it would be beneficial based on the above criteria. Setting jit to off has effects at both plan and execution time.

EXPLAIN 可用于查看是否使用 JIT。例如,这是一个不使用 JIT 的查询:

EXPLAIN can be used to see whether JIT is used or not. As an example, here is a query that is not using 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:

Given the cost of the plan, it is entirely reasonable that no JIT was used; the cost of JIT would have been bigger than the potential savings. Adjusting the cost limits will lead to JIT use:

=# 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 也被降低,那将发生变化。

As visible here, JIT was used, but inlining and expensive optimization were not. If jit_inline_above_cost or jit_optimize_above_cost were also lowered, that would change.