Skip to content
Learn Netverks
1

Why does my query insist on a full table scan? Closed

asked 2 months ago by @qa-0os6puc7ftcbj0fue3ft 0 rep · 105 views

postgresql query optimization

I have a PostgreSQL table partitioned by a datetime field called journeyTime.

If I have a query where the selection criteria is...

WHERE date_trunc('day', journeyTime) = '01-May-2025'

I would expect the explain plan to show that the query optimiser has immediately zoomed in on the single partition that all the records for that date are in.

It doesn't. Instead it does a full table scan on all partitions in the table.

Why?

This question is closed to new answers.

Comments on this question (0)

Use comments to ask for clarification — answers go in the answer box below.

Log in to comment on this question.

6 answers

0

Your query forces a full table scan because applying a function (date_trunc) to the partition key prevents PostgreSQL from using partition pruning. Here's why and how to fix it:

Why This Happens

IssueExplanationFunction on partition keyWHERE date_trunc('day', journeyTime) = '01-May-2025' wraps journeyTime in a function, so Postgres can't match it directly to partition boundariesPartition pruning disabledThe optimizer can't determine which partition contains the data because it would need to evaluate date_trunc() for every rowPostgreSQL limitationAnything more complicated than a simple comparison (>=, <, =) on the partition key won't trigger partition pruning

The Solution

Use a range comparison instead of date_trunc():

sql

-- ❌ Doesn't work (your current query) WHERE date_trunc('day', journeyTime) = '2025-05-01' -- ✅ Works (partition pruning enabled) WHERE journeyTime >= '2025-05-01 00:00:00' AND journeyTime < '2025-05-02 00:00:00'

This allows Postgres to immediately identify the single partition for that day and skip all others.

Additional Tips

  1. Prepare correct timestamps upfront in your application code rather than transforming them in SQL

  2. Make sure journeyTime is the actual partition column declared with PARTITION BY RANGE (journeyTime)

  3. Run ANALYZE on the table to ensure statistics are current, which helps the planner make better decisions

  4. Check PostgreSQL version—partition pruning improved significantly in Postgres 11+ (declarative partitioning) compared to 10.x

The key principle: keep the partition key "bare" in your WHERE clause without wrapping it in functions so the optimizer can use it for partition elimination.

Reese West · 0 rep · 2 months ago

0

Has many characteristics of being AI generated - which is not allowed on this site.

Sam Diaz · 0 rep · 2 months ago

0

How about you show us the explain plan so we can see? (But the other answer is probably correct - but will likely get deleted since it looks to be AI generated).

Also it appears you want a concrete answer, id so, why ask it as an open-ended question for discussion?

Taylor Nguyen · 0 rep · 2 months ago

0

because clicked on the wrong button!

Reese Nguyen · 0 rep · 2 months ago

0

BTW - the AI answer is correct.

Reese Cole · 0 rep · 2 months ago

0

PostgreSQL can only perform partition pruning if the WHERE clause contains a comparison with the partitioning key: one side of the comparison operator must be the plain partitioning key. Burying it inside a function call or other expression won't work.

Assuming that journeytime is a timestamp with time zone and your days begin and end according to UTC, your WHERE condition should be:

WHERE journeytime >= TIMESTAMP WITH TIME ZONE '2025-05-01 00:00:00 UTC'
  AND journeytime < TIMESTAMP WITH TIME ZONE '2025-05-01 00:00:00 UTC' + INTERVAL '1 day'

Cameron Singh · 0 rep · 2 months ago

New answers are not accepted while this question is closed.