JIT编译主要有利于长时间运行、受 CPU 限制的查询。通常情况下,这将是分析查询。对于短查询,执行JIT编译增加的开销通常高于节省的时间。
为了确定是否JIT应使用编译,将使用查询的总预估成本(参见第 68 章和第 19.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 (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_cost 或 jit_optimize_above_cost 也较低,这是会发生变化的。