9.3 9.4 9.5 9.6 10 11 12 13 14 15 Current(16) 17
问题报告 纠错本页面

30.2. 什么时候会用JIT#

JIT编译主要可以让长时间运行的CPU密集型的查询受益。对于短查询,执行JIT编译增加的开销常常比它节省的时间还要多。

为了判断是否应该使用JIT编译,会用到一个查询的总的估计代价(见Chapter 68Section 19.7.2)。查询的估计代价将与jit_above_cost的设置进行比较。如果代价更高,JIT编译将被执行。然后需要两个进一步的决定。首先,如果估计代价超过jit_inline_above_cost的设置,该查询中使用的短函数和操作符都将被内联。其次,如果估计代价超过jit_optimize_above_cost的设置,会应用昂贵的优化来改进产生的代码。这些选项中的每一种都会增加JIT编译的开销,但是可以可观地降低查询执行时间。

这些基于代价的决定将在规划时做出,而不是在执行时做出。这意味着,在使用预备语句并且使用了一个一般性的计划时(见PREPARE),配置参数的值实际上是在预备时控制这些决定,而不是由执行时的设置来决定。

Note

如果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)

鉴于该计划的成本,完全合理没有使用 JITJIT的成本会高于潜在的节省。 调整成本限制将导致使用 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 (Deform 0.000 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,情况将会改变。