PG中的JIT即时编译(Just-In-Time Compilation)

0    1136    5

Tags:

👉 本文共约3156个字,系统预计阅读时间或需12分钟。

官网:http://postgres.cn/docs/13/jit.html

31.1. 什么是JIT编译?

即时(Just-In-Time,JIT)编译( Compilation)是将某种形式的解释程序计算转变成原生程序的过程,并且这一过程是在运行时完成的。例如,与使用能够计算任意SQL表达式的通用代码来计算一个特定的SQL谓词(如WHERE a.col = 3)不同,可以产生一个专门针对该表达式的函数并且可以由CPU原生执行,从而得到加速。

当使用--with-llvm编译PostgreSQL后,PostgreSQL内建支持用LLVM执行JIT编译。

进一步的细节请参考src/backend/jit/README

31.1.1. JIT加速的操作

当前,PostgreSQL的JIT实现支持对表达式计算以及元组拆解的加速。未来可能有更多其他操作采用这种技术加速。

表达式计算被用来计算WHERE子句、目标列表、聚集以及投影。通过为每一种情况生成专门的代码来实现加速。

元组拆解是把一个磁盘上的元组(见第 68.6.1 节)转换成其在内存中表示的过程。通过创建一个专门针对该表布局和要被抽取的列数的函数来实现加速。

31.1.2. 内联

PostgreSQL有很好的扩展性并且允许定义新的数据类型、函数、操作符以及其他数据库对象,见第 37 章。实际上,内建对象都使用近乎完全相同的机制来实现。这种可扩展性隐含了一些开销,例如函数调用带来的开销(见第 37.3 节)。为了降低这类开销,JIT编译可以把小函数的函数体内联到使用它们的表达式中。这种方式可以优化掉可观的开销。

31.1.3. 优化

LLVM支持对生成的代码进行优化。一些优化代价很低,以至于可以在每次使用JIT时都执行,而另一些优化则只有在运行时间较长的查询中才能获益。更多有关优化的细节请参考https://llvm.org/docs/Passes.html#transform-passes。

31.2. 什么时候会用JIT?

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

为了判断是否应该使用JIT编译,会用到一个查询的总的估计代价(见第 70 章第 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的查询:

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!
AiDBA后续精彩内容已被站长无情隐藏,请输入验证码解锁本文!
验证码:
获取验证码: 请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“AiDBA”或者“dbaup6”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复