How Just-in-Time (JIT) Compilation Works in PostgreSQL

Just-in-Time (JIT) Compilation is a technique where code execution is optimized by compiling parts of the code at runtime, rather than before execution. This approach allows for performance improvements by adapting the compiled code to the actual data and workload characteristics encountered during execution.

Why is JIT Important for Databases?

Databases handle diverse workloads, often involving computationally intensive operations such as aggregations, joins, and filtering. Traditional execution methods may not fully exploit hardware capabilities. JIT allows databases to optimize these operations dynamically, leveraging CPU and memory more efficiently to accelerate query execution.

PostgreSQL introduced JIT compilation in version 11, leveraging the LLVM (Low-Level Virtual Machine) compiler framework. It enhances query performance by optimizing key aspects of query execution, especially for complex and analytical queries. By default, JIT is not enabled but can be activated for workloads where it’s beneficial.

How JIT Works in PostgreSQL

PostgreSQL processes queries in a series of steps: parsing, planning, and execution. During execution, operations such as expression evaluation, tuple deforming, and aggregation are performed. These operations can become bottlenecks for computationally intensive queries.

Where JIT Fits into the Execution Pipeline

JIT is applied during the execution phase, specifically targeting areas that involve heavy computation. By compiling and optimizing specific operations at runtime, JIT reduces the time required for repetitive calculations and data processing.

Key Components of JIT in PostgreSQL

1. Expression Evaluation

JIT optimizes the evaluation of WHERE clauses, JOIN conditions, and target list expressions by compiling them into efficient machine code.

2. Tuple Deforming

PostgreSQL retrieves rows in a raw format (tuples) from storage. JIT accelerates the process of converting these tuples into a usable form for query processing.

3. Aggregation

For queries involving aggregates (e.g., SUM, AVG), JIT speeds up the computation by directly generating optimized machine code for these operations.

Benefits of JIT Compilation

JIT (Just-In-Time) compilation provides several significant advantages in database query optimization, particularly for computationally intensive tasks. By dynamically compiling parts of a query into machine code at runtime, JIT reduces the overhead of interpretation, leading to faster execution speeds. This is especially beneficial for queries involving large datasets and complex operations, such as filtering, sorting, and aggregation. JIT excels in scenarios where computational efficiency is critical, such as analytical queries used in data warehousing and reporting. For example, it significantly improves performance for tasks like calculating large aggregates or running intricate filtering conditions across millions of rows. Overall, JIT compilation is a powerful tool for optimizing database performance, particularly in environments where speed and efficiency are paramount.

Enabling JIT in PostgreSQL

Checking if JIT is Supported

JIT in PostgreSQL relies on LLVM. To verify if JIT is supported, use the following SQL command:

SHOW jit;

If JIT is supported, the output will indicate on or off. Ensure that LLVM is installed and correctly configured if it’s not available.

Configuration Settings for JIT

1. jit: Enables or disables JIT globally.

2. jit_above_cost: Sets a cost threshold above which JIT is triggered.

3. jit_inline_above_cost: Specifies the cost threshold for inlining functions.

4. jit_optimize_above_cost: Defines the cost threshold for applying optimizations during JIT.

Practical Steps to Enable JIT

Edit the postgresql.conf file or use SQL commands to enable JIT:

SET jit = on;
SET jit_above_cost = 100000;
SET jit_inline_above_cost = 500000;
SET jit_optimize_above_cost = 500000;

Performance Comparisons

Example: A query performing a large aggregation on a dataset with millions of rows:

Without JIT:

Ensure JIT is off by using the command:

SET jit = off;
jitoff=# Explain analyze SELECT AVG(price) FROM products WHERE category = 'Electronics';
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=194.10..194.11 rows=1 width=32) (actual time=1.787..1.787 rows=1 loops=1)
   ->  Seq Scan on products  (cost=0.00..189.00 rows=2041 width=6) (actual time=0.016..1.413 rows=2041 loops=1)
         Filter: (category = 'Electronics'::text)
         Rows Removed by Filter: 7959
 Planning Time: 0.093 ms
 Execution Time: 1.819 ms
(6 rows)

With JIT enabled:

jiton=# SET jit = on;
SET
jiton=# Explain analyze SELECT AVG(price) FROM products WHERE category = 'Electronics';
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=193.94..193.94 rows=1 width=32) (actual time=0.943..0.944 rows=1 loops=1)
   ->  Seq Scan on products  (cost=0.00..189.00 rows=1973 width=6) (actual time=0.012..0.752 rows=1973 loops=1)
         Filter: (category = 'Electronics'::text)
         Rows Removed by Filter: 8027
 Planning Time: 0.057 ms
 Execution Time: 0.963 ms
(6 rows)

In the first query without JIT, the total planning and execution time was 1.819 ms. After enabling JIT, the same query's execution time improved to 0.963 ms. This demonstrates how JIT reduces execution latency by optimizing computationally expensive operations like aggregation. Such improvements become more pronounced with larger datasets and more complex queries.

Understanding Limitations

Scenarios Where JIT Might Not Help

* Simple queries or those operating on small datasets may not benefit from JIT due to the compilation overhead.

* JIT is most effective for long-running, computationally heavy queries.

Overhead for Small/Simple Queries

JIT introduces a compilation step, which can add slight overhead for queries that would otherwise execute quickly without JIT.

Dependency on LLVM and Its Version

JIT requires LLVM to be installed. Compatibility depends on the PostgreSQL and LLVM versions. Upgrading LLVM may be necessary for optimal performance.

JIT compilation in PostgreSQL represents a significant leap in query optimization, particularly for computationally intensive and analytical workloads. By leveraging LLVM to dynamically compile and optimize code paths during query execution, PostgreSQL achieves faster execution times and better resource utilization. While JIT's benefits are most evident in complex queries, its overhead for simpler queries highlights the importance of proper configuration and use cases. As PostgreSQL continues to evolve, JIT will likely become an integral feature for achieving high-performance data processing in diverse environments.

Get detailed insights on configuring incremental backups in PostgreSQL. Safeguard your database with effective backup solutions tailored for your needs.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message