Hi all,
I noticed that when creating a partial index with multiple predicates in the WHERE clause, the order in which I write the predicates appears to affect the index build time (specifically the index validation phase).
I created an index with this WHERE clause:
CREATE INDEX CONCURRENTLY idx_v1
ON my_table (tenant_id, jsonb_extract_path_text(data, 'field1'), object_type, id)
WHERE deleted IS NULL
AND jsonb_extract_path_text(data, 'field1') <> ''
AND object_type = 'SpecificType';
Then I tried reordering the predicates to put expensive operations last:
CREATE INDEX CONCURRENTLY idx_v2
ON my_table (tenant_id, jsonb_extract_path_text(data, 'field1'), object_type, id)
WHERE deleted IS NULL
AND object_type = 'SpecificType'
AND jsonb_extract_path_text(data, 'field1') <> '';
The second version (idx_v2) was significantly faster to build
Looking at the PostgreSQL source, it appears that:
- Regular query WHERE clauses go through the planner's order_qual_clauses()
function (in createplan.c), which sorts predicates by cost
- Partial index predicates appear to go through ExecPrepareQual() (in execExpr.c),
which processes predicates in the given order without reordering
This seems to be a difference between how the planner handles query predicates versus how the executor handles index predicates.
Is this expected/intended behavior?
Is there a reason partial index predicates aren't reordered by cost?
I'm using Postgres 16.9
Thanks for any insights!
Arik Schimmel