携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天
JIT(just in time)即时编译是指将某种形式的解释程序计算转变成原生程序的过程,并且这一过程是在运行时完成的。
pg11开始支持这一功能,目前支持tuple deform(将磁盘上的tuple转换为内存中TUPLE格式),以及表达式(select, where, 等语义中的表达式,操作符运算,UDF等)的动态编译。
想要使用JIT功能,首先需要在编译数据库时指定–with-llvm参数,然后才可以在数据库中使用JIT来进行加速。
但是JIT并不是所有情况下都适用的,主要适合那些长时间允许的cpu密集型查询,而一些短查询,JIT编译本身带来的开销可能都会比其节省的时间要大。
JIT的几个主要控制参数如下:
1、jit (boolean)
默认ON,表示开启JIT。
2、jit_above_cost (floating point)
默认100000,当planner发现COST大于这个值时,优化器会启用JIT动态编译。
3、jit_optimize_above_cost (floating point)
默认500000,当planner发现COST大于这个值时,优化器会启用JIT动态编译优化。
4、jit_inline_above_cost (floating point)
默认500000,当planner发现COST大于这个值时,优化器会对用户自定义函数、操作符(目前仅支持C, internal类型的函数)启用JIT优化。
例子:
–一个普通的查询:
可以看到优化器并没有选择JIT编译,因为这里不使用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_above_cost设置为10来强制开启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功能主要适合于那些对大量数据运算(比如说where条件中过滤大量的数据,聚合计算大量的数据等)的效率提升非常的明显,而对于普通的查询JIT反而没有太大帮助。