Quantcast
Channel: Planet PostgreSQL
Viewing all articles
Browse latest Browse all 9712

Deepak Mahto: Exploring PostgreSQL 17: A Developer’s Guide to New Features – Part 2 – Null’s Constraint and Performance.

$
0
0

PostgreSQL 17 Beta was released on May 23, 2024, introducing a host of exciting new features anticipated to be part of the official PostgreSQL 17 release. In this blog series, we’ll delve into these features and explore how they can benefit database developers and migration engineers transitioning to the latest PostgreSQL version.

First part of the blog was on newer features with PL\pgSQL – Procedural language in PostgreSQL 17.

Part 2 is on newer addition that include leveraging constraint information for performance improvement. Databases Constraint bring values to overall data by imposing functionality checks for data quality and need to be govern by each and every rows within a Table. Null constraint is one such considerations that enforces checks whether data on a columns should be always populated or can be ignored. Using constraint for performance improvement is quite common in multiple RDBMS, i had publish a blog that capture constraint and performance comparision for Oracle and PostgreSQL in past.

With PostgreSQL 17 Beta, we have new improvements that consider null constraint for performance improvements as part of underlying execution plans.

Starting with 17 release, PostgreSQL can remove redundant IS NOT NULL statements from execution on columns that have a NOT NULL constraint, and no longer needs to do work on queries that contain an IS NULL clause on an IS NOT NULL column.

Let’s explore these new features with a sample table t1 created using generate_series, with the default constraint of columns being nullable.

pg17=# create table t1 as 
select col1,  random(1,99999999) col2, 
random(11.99,99.99) col3, 
random(1,99999999)::text col4 
from generate_series(1,100) as col1;
SELECT 100
pg17=# \d t1
                 Table "public.t1"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 col1   | integer |           |          |
 col2   | integer |           |          |
 col3   | numeric |           |          |
 col4   | text    |           |          |

As a next step, let’s explore the underlying execution plan for both conditions: col1 IS NULL and col1 IS NOT NULL on column col1 with the default constraint as nullable.

PostgreSQL 17 – NULL Constraint and Performance Improvements

Below table summarizes the underlying execution plan for both conditions (IS NULL and IS NOT NULL) on table columns with the default nullable constraint.

IS NULLIS NOT NULL

pg17=# explain (analyze, buffers, costs off) select count(1) from t1 where col1 is null;


Aggregate (actual time=0.022..0.023 rows=1 loops=1)
Buffers: shared hit=1
-> Seq Scan on t1 (actual time=0.020..0.020 rows=0 loops=1)
Filter: (col1 IS NULL)

Rows Removed by Filter: 100
Buffers: shared hit=1
Planning Time: 0.047 ms
Execution Time: 0.042 ms
(8 rows)
pg17=# explain (analyze, buffers, costs off) select count(1) from t1 where col1 is not null;


Aggregate (actual time=0.035..0.036 rows=1 loops=1)
Buffers: shared hit=1
-> Seq Scan on t1 (actual time=0.013..0.025 rows=100 loops=1)
Filter: (col1 IS NOT NULL)

Buffers: shared hit=1
Planning Time: 0.047 ms
Execution Time: 0.055 ms
(7 rows)
Execution Plan – PostgreSQL 17 (IS NULL and IS NOT NULL)

Observation – Execution Plans – With No NOT NULL Constraint

  • Based on the condition in the SQL query, the necessary filter condition is applied to the table access path, i.e., a sequential scan in this example.

Filter: (col1 IS NULL) / Filter: (col1 IS NOT NULL)

  • Any constraint defined on columns has the potential to influence the filter condition to avoid checks that are guaranteed by the constraint itself. For example, a NOT NULL constraint guarantees that all columns have valid data with no missing values.

As a next step, we will introduce a NOT NULL constraint on the same column as used in the previous example, i.e., col1.

pg17=# alter table t1 alter column col1 set not null;
ALTER TABLE

pg17=# \d t1
                 Table "public.t1"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 col1   | integer |           | not null |
 col2   | integer |           |          |
 col3   | numeric |           |          |
 col4   | text    |           |          |

Execution Plans – post Including NOT NULL constraint

We are re-running the same SQL queries, but now the column in the condition, i.e., col1, is re-defined with a NOT NULL constraint.

PG 17 – IS NULL FilterPG 17 – IS Not NULL Filter
pg17=# explain (analyze, buffers, costs off) select count(1) from t1 where col1 is null;

Aggregate (actual time=0.003..0.004 rows=1 loops=1)
-> Result (actual time=0.001..0.001 rows=0 loops=1)
One-Time Filter: false

Planning Time: 0.040 ms
Execution Time: 0.021 ms
(5 rows)
pg17=# explain (analyze, buffers, costs off) select count(1) from t1 where col1 is not null;

Aggregate (actual time=0.032..0.033 rows=1 loops=1)
Buffers: shared hit=1
-> Seq Scan on t1 (actual time=0.011..0.020 rows=100 loops=1)
Buffers: shared hit=1
Planning Time: 0.046 ms
Execution Time: 0.051 ms
(6 rows)
Execution Plan – PostgreSQL 17 (IS NULL and IS NOT NULL) with Not Null Constraint

Observations – Execution Plan – With NOT NULL Constraint

  • Based on the condition in the SQL, the necessary filter condition is optimized for the IS NULL check due to the col1 constraint. No actual access is performed because the filter condition contradicts the existing NOT NULL constraint on the table. The execution plan effectively skips any access to the actual tables.

One-Time Filter: false

  • When the IS NOT NULL condition is applied, you will notice no filter condition is introduced to check the condition provided in the SQL. This is because the column is defined with a NOT NULL constraint, which eliminates the need for PostgreSQL to recheck the filter condition, thereby reducing marginal processing efforts.
With NOT NULL Constraint
Seq Scan on t1 (actual time=0.011..0.020 rows=100 loops=1)
Without NOT NULL Constraint
Seq Scan on t1 (actual time=0.013..0.025 rows=100 loops=1)
Filter: (col1 IS NOT NULL)
Filter Condition – Not Null – PG17

IS DISTINCT FROM and IS NOT DISTINCT FROM Considerations.

When discussing comparisons involving NULL values along with IS or IS NOT, we can also consider the IS DISTINCT FROM and IS NOT DISTINCT FROM conditions. If you’re wondering what IS DISTINCT FROM and IS NOT DISTINCT FROM entail, feel free to check out one of my previous blogs for deeper insights.

The underlying execution plan exhibits similar characteristics to those observed for IS NOT NULL and IS NULL conditions.

PG 17 – col1 is not distinct from nullPG 17 – col1 is distinct from null
pg17=# explain (analyze, buffers, costs off) select count(1) from t1 where col1 is not distinct from null;


Aggregate (actual time=0.004..0.004 rows=1 loops=1)
-> Result (actual time=0.001..0.001 rows=0 loops=1)
One-Time Filter: false

Planning Time: 0.076 ms
Execution Time: 0.023 ms
(5 rows)
pg17=# explain (analyze, buffers, costs off) select count(1) from t1 where col1 is distinct from null;


Aggregate (actual time=0.044..0.044 rows=1 loops=1)
Buffers: shared hit=1
-> Seq Scan on t1 (actual time=0.023..0.032 rows=100 loops=1)
Buffers: shared hit=1
Planning Time: 0.057 ms
Execution Time: 0.063 ms
(6 rows)
Execution Plan – PostgreSQL 17 (is not distinct from null and is distinct from null) with Not Null Constraint

Conclusion

Delving into constraints and curating performance improvements is an interesting and exciting addition. It encourages Database Modelers or Designers to further extend business functionality with constraints within Databases, benefiting not only in terms of functionality but also enhancing performance. In this exploration of PostgreSQL 17, we’ve uncovered significant advancements in leveraging constraints for performance enhancements. With improvements like removing redundant checks and optimizing filter conditions, PostgreSQL empowers developers to elevate database functionality with constraints while enhancing performance.


Viewing all articles
Browse latest Browse all 9712

Trending Articles