Re: [GENERAL] Row value expression much faster than equivalent OR clauses

Поиск
Список
Период
Сортировка
От Merlin Moncure
Тема Re: [GENERAL] Row value expression much faster than equivalent OR clauses
Дата
Msg-id CAHyXU0ywHJwzVfGH-OvRB2jMea212r620wq0F2B-bFst9LPGPg@mail.gmail.com
обсуждение исходный текст
Ответ на Re: [GENERAL] Row value expression much faster than equivalent OR clauses  (Kevin Grittner <kgrittn@gmail.com>)
Список pgsql-general
On Wed, Jan 4, 2017 at 8:49 AM, Kevin Grittner <kgrittn@gmail.com> wrote:
> On Wed, Dec 28, 2016 at 10:58 AM, Steven Grimm <sgrimm@thesegovia.com> wrote:
>
>> WHERE ((e.timeStamp > '2016-12-19T20:34:22.315Z')
>>         OR (e.timeStamp = '2016-12-19T20:34:22.315Z'
>>             AND e.sequenceNumber > 0)
>>         OR (e.timeStamp = '2016-12-19T20:34:22.315Z'
>>             AND e.sequenceNumber = 0
>>             AND e.aggregateIdentifier >
>> 'dev:642e1953-2562-4768-80d9-0c3af9b0ff84'))
>
>> This uses the index on the three columns it's using for ordering of events,
>> but (if I'm reading the explain output correctly) does a full scan of the
>> index.
>
>> I played around with it a little and one thing I tried was to restructure
>> the WHERE clause using a row value expression that's semantically equivalent
>> to the original.
>
>> WHERE (e.timeStamp, e.sequenceNumber, e.aggregateIdentifier) >
>>         ('2016-11-19T20:34:22.315Z', 0, 'dev:642e1953-2562-4768-80d9-0c3af9b0ff84')
>
>> This ends up being a LOT faster:
>
> Yup.
>
>> I wonder if the query planner could recognize that the two queries are
>> equivalent and choose the second plan for the OR-clause version, or at least
>> use the index more efficiently.
>
> Theoretically it could, but that would add significant time to
> planning for a large number of queries, with no benefit to those
> who explicitly write the query in the faster (and more concise!)
> fashion.
>
> You could come a lot closer to the performance of the row value
> expression technique by using the logical equivalent of your
> original query that puts AND at the higher level and OR at the
> lower level.  (Having OR at the top is generally inefficient.)
>
> WHERE (e.timeStamp >= '2016-12-19T20:34:22.315Z'
>   AND (e.timeStamp >  '2016-12-19T20:34:22.315Z'
>      OR (e.sequenceNumber >= 0
>     AND (e.sequenceNumber >  0
>        OR (e.aggregateIdentifier >
> 'dev:642e1953-2562-4768-80d9-0c3af9b0ff84')))))

In practice this can utilize the first part of the key only.  So
performance will be good if "timeStamp" is selective and poor if it
isn't.   In this query, I'd venture to guess it'd be pretty good.  The
row-wise comparison feature was built specifically to handle this type
of query and it's additionally much more concise as you noted, so I'd
agree; effort is better spent on client side education than on complex
rewriting strategies.

This type of query comes up a lot in applications that were converted from ISAM.

merlin


В списке pgsql-general по дате отправления:

Предыдущее
От: Rob Sargent
Дата:
Сообщение: Re: [GENERAL] COPY: row is too big
Следующее
От: Israel Brewster
Дата:
Сообщение: Re: [GENERAL] Improve PostGIS performance with 62 million rows?