Thread

  1. Question about partial index WHERE clause predicate ordering

    Arik Schimmel <arik.schimmel@wiz.io> — 2025-12-24T12:48:22Z

    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