Re: Index Searches higher than expected for skip scan

From: Michael Christofides <michael(at)pgmustard(dot)com>
To: Peter Geoghegan <pg(at)bowt(dot)ie>
Cc: pgsql-performance(at)lists(dot)postgresql(dot)org
Subject: Re: Index Searches higher than expected for skip scan
Date: 2025-11-07 11:16:34
Message-ID: CAFwT4nCcW5_3=Mvp8u5F4tk8D_QRWrjqsNoQY1BeL0hd1Pnyug@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-performance

Thank you for the incredibly helpful (and fast) replies Peter.

> Attached is its output when I run your test query. The issue here is

that skip scan thinks that there are 4 distinct skip array values that

it must use:

1. SK_BT_MINVAL

2. false

3. true

4. SK_ISNULL

This output in particular really helped it make sense to me.

> But if the column *was* nullable, adding IS NOT NULL would cut the

number of index searches by 1.
>

Nice idea. Once it sunk in, I realised I could try the explicit "AND
boolean_field IN (true, false)" and got it down to 2 index searches:

EXPLAIN (ANALYZE, BUFFERS, VERBOSE, SETTINGS)
SELECT boolean_field FROM example WHERE integer_field = 5432 AND
boolean_field IN (true, false);

QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------
Index Only Scan using bool_int_idx on public.example (cost=0.29..8.79
rows=10 width=1) (actual time=0.060..0.077 rows=12.00 loops=1)
Output: boolean_field
Index Cond: ((example.boolean_field = ANY ('{t,f}'::boolean[])) AND
(example.integer_field = 5432))
Heap Fetches: 0
Index Searches: 2
Buffers: shared hit=5
Planning Time: 0.265 ms
Execution Time: 0.115 ms

Thanks again,
Michael

In response to

Responses

Browse pgsql-performance by date

  From Date Subject
Next Message Peter Geoghegan 2025-11-07 15:00:49 Re: Index Searches higher than expected for skip scan
Previous Message Peter Geoghegan 2025-11-06 20:39:24 Re: Index Searches higher than expected for skip scan