Recognizing range constraints (was Re: [PERFORM] Plan for relatively simple query seems to be very inefficient)

От: Tom Lane
Тема: Recognizing range constraints (was Re: [PERFORM] Plan for relatively simple query seems to be very inefficient)
Дата: ,
Msg-id: 6326.1112825377@sss.pgh.pa.us
(см: обсуждение, исходный текст)
Ответы: Re: Recognizing range constraints (was Re: [PERFORM] Plan for relatively simple query seems to be very inefficient)  ("Jim C. Nasby")
Re: Recognizing range constraints (was Re: [PERFORM] Plan for  (Simon Riggs)
Re: Recognizing range constraints (was Re: Plan for relatively simple query seems to be very inefficient)  (Bruno Wolff III)
Список: pgsql-hackers


I wrote:
> Arjen van der Meijden <> writes:
>> SELECT COUNT(*) FROM
>> data_main AS dm,
>> postcodes AS p
>> WHERE dm.range BETWEEN p.range_from AND p.range_till

> Planner error ... because it doesn't have any good way to estimate the
> number of matching rows, it thinks that way is a bit more expensive than
> data_main as the outside, but in reality it seems a good deal cheaper:

BTW, it would get the right answer if it had recognized the WHERE clause
as a range restriction --- it still doesn't know exactly what fraction
of rows will match, but its default estimate is a great deal tighter for
"WHERE x > something AND x < somethingelse" than it is for two unrelated
inequality constraints.  Enough tighter that it would have gone for the
correct plan.

The problem is that it doesn't recognize the WHERE as a range constraint
on dm.range.  I thought for a moment that this might be a
recently-introduced bug, but actually the code is operating as designed:
clauselist_selectivity says

         * See if it looks like a restriction clause with a pseudoconstant
         * on one side.  (Anything more complicated than that might not
         * behave in the simple way we are expecting.)

"Pseudoconstant" in this context means "a constant, parameter symbol, or
non-volatile functions of these" ... so comparisons against values from
another table don't qualify.  It seems like we're missing a bet though.

Can anyone suggest a more general rule?  Do we need for example to
consider whether the relation membership is the same in two clauses
that might be opposite sides of a range restriction?  It seems like

    a.x > b.y AND a.x < b.z

probably can be treated as a range restriction on a.x for this purpose,
but I'm much less sure that the same is true of

    a.x > b.y AND a.x < c.z

Thoughts?

            regards, tom lane


В списке pgsql-hackers по дате сообщения:

От: "Mike G."
Дата:
Сообщение: Did this issue ever get resolved?
От: Tom Lane
Дата:
Сообщение: Re: prepared statements don't log arguments?