背景
技术讲解
即时编译(Just-In-Time,JIT)可以将某种形式的解释程序计算转变成原生程序,由CPU原生执行,从而得到加速。
使用场景
JIT编译技术可以让CPU密集型的查询受益。PostgreSQL的JIT实现支持对表达式计算以及元组拆解的加速。表达式计算的应用包括WHERE子句、目标列表、聚集以及投影。PostgreSQL通过为每一种情况生成专门的代码来实现加速。
例子
创建测试表,并写入一亿行数据。
createtable jit_test (id serial);insertINTO jit_test (id)select*from generate_series(1,100000000);‘ analyze jit_test;
关闭JIT进行优化性能测试
postgres=# explain analyze select avg(id)from jit_test; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- Finalize Aggregate (cost=453326.89..453326.90 rows=1 width=32)(actual time=13444.050..13444.050 rows=1 loops=1)-> Gather Motion 3:1(slice1; segments:3)(cost=453326.83..453326.88 rows=3 width=32)(actual time=13064.601..13444.006 rows=3 loops=1)-> Partial Aggregate (cost=453326.83..453326.84 rows=1 width=32)(actual time=13443.451..13443.452 rows=1 loops=1)-> Seq Scan on jit_test (cost=0.00..369995.67 rows=33332467 width=4)(actual time=0.191..7151.999 rows=33335145 loops=1) Optimizer: Postgres query optimizer Planning Time:0.447 ms (slice0) Executor memory:40K bytes. (slice1) Executor memory:38K bytes avg x 3 workers,38K bytes max (seg0). Memory used:128000kB Execution Time:13445.055 ms (10 rows)
打开JIT相关参数
set jit to on;set optimizer to off;
开启JIT进行性能优化测试
QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- Finalize Aggregate (cost=453326.89..453326.90 rows=1 width=32)(actual time=11695.112..11695.113 rows=1 loops=1)-> Gather Motion 3:1(slice1; segments:3)(cost=453326.83..453326.88 rows=3 width=32)(actual time=10926.392..11690.101 rows=3 loops=1)-> Partial Aggregate (cost=453326.83..453326.84 rows=1 width=32)(actual time=11693.964..11693.965 rows=1 loops=1)-> Seq Scan on jit_test (cost=0.00..369995.67 rows=33332467 width=4)(actual time=0.213..6529.483 rows=33335145 loops=1) Optimizer: Postgres query optimizer Planning Time:0.492 ms (slice0) Executor memory:40K bytes. (slice1) Executor memory:38K bytes avg x 3 workers,38K bytes max (seg0). Memory used:128000kB JIT: Functions:4 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 0.870 ms, Inlining 0.000 ms, Optimization 0.295 ms, Emission 4.462 ms, Total 5.627 ms Execution Time:11697.065 ms (14 rows)
可以看到在大数据集时,对于单列聚集的场景 ,使用JIT进行计算会有15%-20%的性能提升。JIT编译技术可以让CPU密集型的查询受益,并且这个性能提升会随着数据量的增大而更加明显。但是需要注意的是,JIT在小数据集的场景下反而会因为有额外的JIT开销,其编译增加的时间比其节省的时间还要多,从而导致性能下降。用户需要根据自己的实际业务场景谨慎使用JIT。
总结
JIT 技术对与OLAP数据库来说是有效加速CPU密集型查询能力的有效手段,目前PostgreSQL完成了WHERE子句、目标列表、聚集以及投影等方面的工程实现。其实现场景还相对比较少,而ADBPG7未来的自研执行向量化引擎则在更多的场景尝试引入JIT技术来进一步提升查询性能。