第 31 章 即时编译(JIT)
目录
本章解释什么是即时编译,以及如何在 PostgreSQL 中配置它。
31.1. 什么是 JIT 编译?#
即时(Just-In-Time,JIT)编译是在运行时将某种形式的解释式程序求值转换为原生程序的过程。例如,计算某个特定的 SQL 谓词(如 WHERE a.col = 3)时,可以生成一个专用于该表达式、由 CPU 原生执行的函数,以取代能够对任意 SQL 表达式求值的通用代码,从而加快执行速度。
当 PostgreSQL 使用
--with-llvm
构建时,PostgreSQL 内置了使用 LLVM
执行 JIT 编译的支持。
更多细节参见 src/backend/jit/README。
31.1.1. JIT 加速的操作 #
当前,PostgreSQL 的 JIT 实现支持对表达式求值和元组拆解进行加速。未来还可能加速其他若干操作。
表达式求值用于计算 WHERE 子句、目标列表、聚合和投影。它可以通过为每种情况生成专用代码来加速。
元组拆解是将磁盘上的元组(见第 69.6.1 节)转换为其内存表示的过程。它可以通过创建一个针对表布局和要提取的列数的专用函数来加速。
31.1.2. 内联 #
PostgreSQL 具有很强的可扩展性,允许定义新的数据类型、函数、操作符以及其他数据库对象;见第 37 章。实际上,内置对象几乎也是通过相同的机制实现的。这种可扩展性意味着会有一些额外开销,例如函数调用带来的开销(见第 37.3 节)。为了减少这类开销,JIT 编译可以把小函数的函数体内联到使用它们的表达式中,从而优化掉相当一部分开销。
31.1.3. 优化 #
LLVM 支持对生成的代码进行优化。有些优化的代价很低,因此每次使用 JIT 时都可以执行;另一些优化则只有在运行时间较长的查询中才有益处。更多有关优化的细节请参见 https://llvm.org/docs/Passes.html#transform-passes。