Re: Why is the optimiser choosing the slower query, or, understanding explain analyze output

From: Jeff Janes <jeff(dot)janes(at)gmail(dot)com>
To: Alistair Bayley <alistair(at)abayley(dot)org>
Cc: "pgsql-performance(at)postgresql(dot)org" <pgsql-performance(at)postgresql(dot)org>
Subject: Re: Why is the optimiser choosing the slower query, or, understanding explain analyze output
Date: 2014-02-17 22:48:44
Message-ID: CAMkU=1x16-S5V+BKD0Pr2K3NyCQvv7hsCP1Fk4UcwHecssV_KQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-performance

On Mon, Feb 17, 2014 at 1:54 PM, Alistair Bayley <alistair(at)abayley(dot)org>wrote:

> I have postgresql 8.4.15 on Ubuntu 10.04 and this query:
>
> SELECT MAX(probeTable.PROBE_ALARM_EVENT_ID) AS MAX_EVENT_ID
> FROM ALARM_EVENT eventTable
> INNER JOIN ALARM_EVENT_PROBE probeTable
> ON eventTable.ALARM_EVENT_ID = probeTable.ALARM_EVENT_ID
> WHERE probeTable.PROBE_ID = 2
>
> which is running slower than it could. Table definitions and explain
> analyze output below.
> The first explain is the current plan (uses sequential scans).
> The second is after I have disabled sequential scans, and is the plan
> I would prefer.
>
> I have vacuum analyzed both tables. In terms of relevant changes to
> the default postgresql.conf, we have these:
>
> shared_buffers = 28MB
> constraint_exclusion = on
>
> I want to understand why the optimiser is choosing the plan with
> sequential table scans, rather than the plan with index scans.
> I am not sure how to interpret the predicted vs actual times/costs,
> and want to understand why the predicted cost for the index scan plan
> seems to be way off.
>

The planner clamps the estimated number of rows from an index scan at 1
row, even if it actually believes the number will be 0. That makes the
logical simpler, avoiding needs to test for division by zero all over the
place, and probably makes it more robust to mis-estimation in most use
cases. But in this case, that means it thinks it will find 34 rows, one
from each partition, which is way too high.

Now, there certainly is some cost to test an index and finding that no rows
in it can match. But your query is probably probing the same spot in each
index for each negative match, which means all the blocks are already in
memory. But PostgreSQL doesn't know that, so even if it didn't do the
clamp it would probably still not get the right answer.

Cheers,

Jeff

In response to

Responses

Browse pgsql-performance by date

  From Date Subject
Next Message KONDO Mitsumasa 2014-02-18 01:23:09 Re: Optimal settings for RAID controller - optimized for writes
Previous Message David Wall 2014-02-17 22:14:44 DB size and TABLE sizes don't seem to add up