Очень большое время планирования запросов для базы данных с большим количеством разделов в PostgreSQL - PullRequest
0 голосов
/ 21 января 2019

У меня есть база данных PostgreSQL 10, которая содержит две таблицы, каждая из которых имеет два уровня разбиения (по спискам).

Данные теперь хранятся в секционированных таблицах от 5 до 10 КБ (внуки двух таблиц, упомянутых выше) в зависимости от дня.

В таблице разделов grand-child имеется три индекса, но два столбца, для которых выполняется разбиение, не индексируются. (Так как я не думаю, что это нужно, нет?)

Проблема, которую я наблюдаю, заключается в том, что время планирования запроса очень медленное, но время выполнения запроса очень быстрое.

Даже когда значения разделов были жестко запрограммированы в запросе.

Исследуя проблему, я подумал, что причиной этого было использование линейного поиска в PostgreSQL 10 для поиска метаданных раздела.

ср: https://blog.2ndquadrant.com/partition-elimination-postgresql-11/

Поэтому я решил попробовать PostgreSQL 11, который включает в себя два вышеупомянутых патча:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=499be013de65242235ebdde06adb08db887f0ea5 https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=9fdb675fc5d2de825414e05939727de8b120ae81

Хелас, похоже, что смена версии ничего не меняет.

Теперь я знаю, что наличие большого количества разделов не очень ценится PostgreSQL, но я все же хотел бы понять, почему планировщик запросов работает так медленно в PostgreSQL 10, а теперь и в PostgreSQL 11.

Примером запроса может быть:

EXPLAIN ANALYZE
SELECT
    table_a.a,
    table_b.a
FROM
    (
        SELECT
            a,
            b
        FROM
            table_a
        WHERE
            partition_level_1_column = 'foo'
            AND
            partition_level_2_column = 'bar'
    )
        AS table_a
INNER JOIN
    (
        SELECT
            a,
            b
        FROM
            table_b
        WHERE
            partition_level_1_column = 'baz'
            AND
            partition_level_2_column = 'bat'
    )
        AS table_b
        ON table_b.b = table_a.b
LIMIT
    10;

При запуске в базе данных с разделами 5K будет возвращено Planning Time: 7155.647 ms, но Execution Time: 2.827 ms.

...