Re: Avoid full GIN index scan when possible

Поиск
Список
Период
Сортировка
От Alexander Korotkov
Тема Re: Avoid full GIN index scan when possible
Дата
Msg-id CAPpHfdthhf8S-UjE46hjy+g7pgGhy=hav1-BUmQq6+hKmY13nA@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Avoid full GIN index scan when possible  (Tomas Vondra <tomas.vondra@2ndquadrant.com>)
Ответы Re: Avoid full GIN index scan when possible
Список pgsql-hackers
Hi, Tomas!

Thank you for your feedback!

On Mon, Jan 6, 2020 at 6:22 PM Tomas Vondra <tomas.vondra@2ndquadrant.com> wrote:
Yeah, I can confirm those results, although on my system the timings are
a bit different (I haven't tested v8):

                                        |        Query time, ms
             WHERE condition            | master |    v9
---------------------------------------+--------+---------
  a @> '{}'                             |    610 |    589
  a @> '{}' and b @> '{}'               |    185 |    665
  a @> '{}' and b @> '{}' and c @> '{}' |    185 |    741

So that's something we probably need to address, perhaps by using the
GIN_CAT_EMPTY_QUERY entries as proposed.

Yeah, handling nulls better without regression in some cases is hard.
For now I see at least 3 different ways of nulls handling, assuming there
is another non-excluding scan key:

1) Collect non-null matches by full scan of all non-null entries.
2) Exclude null marches using scan of null entry.
3) Force recheck.

Each method have its own advantages and disadvantages.  We probably
would need some cost-based decision making algorithm based on statistics.
I'm not entirely sure it's OK to do this execution time.  However, it probably
could be classified as "adaptive query processing", which is considered as
cool trend in DBMS.

Attached version 10 of patch doesn't change null handling in comparison
with master.  It eliminates full index scan only if there is another scan on the
same column.  So, it never adds null item to the scan key.  I've rerun tests
from Nikita [1].

   |                                        | Query time, ms |
 # |             WHERE condition            | master |   v10 |
---+----------------------------------------+--------+-------+
 1 |  a @> '{}'                             |    223 |   218 |
 2 |  a @> '{}' and b @> '{}'               |    302 |   308 |
 3 |  a @> '{}' and b @> '{}' and c @> '{}' |    405 |   404 |
 4 |  a @> '{}' and a @@ '1'                |     59 |   0.3 |
 5 |  a @> '{}' and a @@ '-1'               |     64 |   2.2 |
 6 |  a @@ '!-1' and a @@ '1'               |     63 |   0.3 |
 7 |  a @@ '!1' and a @@ '-1'               |     62 |   3.0 |

It appears that absolute numbers for master are higher than they were
previous time [2].  I've rechecked multiple times that current numbers are
correct.  So, it might be I didn't turn off sequential scan previous time.

We can see that cases #1, #2, #3, which have quals over multiple attributes
have the same execution time as in master.  That's expected since scanning
strategy is the same.  Cases #4, #5, #6, #7 have about the same improvement
as in v9.

I've also rerun many nulls test from Nikita [3].

                                       | Query time, ms |
            WHERE condition            | master |   v10 |
---------------------------------------+--------+-------+
 a @> '{}'                             |    190 |   192 |
 a @> '{}' and b @> '{}'               |     55 |    57 |
 a @> '{}' and b @> '{}' and c @> '{}' |     60 |    58 |

The results are the same as in master again.

I've also tested this on a database storing mailing lists archives with
a trigram index, and in that case the performance with short values gets
much better. The "messages" table has two text fields with a GIN trigram
index - subject and body, and querying them with short/long values works
like this:

                    WHERE                    |  master  |    v9
  --------------------------------------------------------------
  subject LIKE '%aa%' AND body LIKE '%xx%'   |    4943  |  4052
  subject LIKE '%aaa%' AND body LIKE '%xx%'  |      10  |    10
  subject LIKE '%aa%' AND body LIKE '%xxx%'  |     380  |    13
  subject LIKE '%aaa%' AND BODY LIKE '%xxx%' |       2  |     2

which seems fairly nice. I've done tests with individual columns, and
that seems to be working fine too.

Cool, thanks!

So, I think v10 is a version of patch, which can be committed after
some cleanup.  And we can try doing better nulls handling in a separate
patch.

Links

------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company 
Вложения

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

Предыдущее
От: Stephen Frost
Дата:
Сообщение: Re: weird libpq GSSAPI comment
Следующее
От: Alvaro Herrera
Дата:
Сообщение: Re: xact_start for walsender & logical decoding not updated