@jonasas

Почему медленная выборка в партицированных таблицах Postgresql?

Доброго времени суток!
Я использую Postgresql 9.5. Настройки из коробки.
Разбил таблицу на ~7000 партиций. Вставил одну запись.
Когда делаю SELECT * FROM "Offer";, запрос длится 1,5 сек.
Когда делаю SELECT * FROM "Offer" WHERE bid=4793;, где bid -- ограничение партиционирования (по одной таблице на каждое значение bid), запрос длится 1 секунду.

Вот EXPLAIN ANALYZE для второго варианта:
Append  (cost=0.00..12.14 rows=2 width=596) (actual time=0.014..0.014 rows=1 loops=1)
  ->  Seq Scan on "Offer"  (cost=0.00..1.01 rows=1 width=344) (actual time=0.011..0.011 rows=0 loops=1)
        Filter: (bid = 4793)
        Rows Removed by Filter: 1
  ->  Seq Scan on "Offer-4793"  (cost=0.00..11.12 rows=1 width=848) (actual time=0.002..0.002 rows=1 loops=1)
        Filter: (bid = 4793)
Planning time: 996.243 ms
Execution time: 0.261 ms


Почему так долго? Чем можно профилировать это всё?
У меня есть единственное предположение -- postgresql не держит в озу условия ограничений своих партиций и каждый раз читает с диска.

Очень рассчитываю на помощь!

UPDATE:
Ещё мне посоветовали каскадное партицирование (у основной таблицы 10 детей, у каждого из которых тоже по десять детей итд). Результат не лучше:
Append  (cost=0.00..12.24 rows=5 width=848) (actual time=0.013..0.013 rows=1 loops=1)
  ->  Seq Scan on "Offer"  (cost=0.00..1.11 rows=1 width=848) (actual time=0.006..0.006 rows=0 loops=1)
    Filter: (bid = 4793)
  ->  Seq Scan on "Offer-ddd-3"  (cost=0.00..0.00 rows=1 width=848) (actual time=0.001..0.001 rows=0 loops=1)
    Filter: (bid = 4793)
  ->  Seq Scan on "Offer-dd-33"  (cost=0.00..0.00 rows=1 width=848) (actual time=0.000..0.000 rows=0 loops=1)
    Filter: (bid = 4793)
  ->  Seq Scan on "Offer-d-336"  (cost=0.00..0.00 rows=1 width=848) (actual time=0.000..0.000 rows=0 loops=1)
    Filter: (bid = 4793)
  ->  Seq Scan on "Offer-4793"  (cost=0.00..11.12 rows=1 width=848) (actual time=0.006..0.006 rows=1 loops=1)
    Filter: (bid = 4793)
Planning time: 1449.872 ms
Execution time: 0.354 ms
  • Вопрос задан
  • 734 просмотра
Пригласить эксперта
Ответы на вопрос 3
а у вас индексы по этим полям в дочерних таблицах есть?

https://www.postgrespro.ru/doc/ddl-inherit.html#DD...
Возможности наследования серьёзно ограничены тем, что индексы (включая ограничения уникальности) и ограничения внешних ключей относятся только к отдельным таблицам, но не к их потомкам. Это касается обеих сторон ограничений внешних ключей. Таким образом, применительно к нашему примеру:
Ответ написан
Melkij
@Melkij
PostgreSQL DBA
Покажите explain analyze. Судя по cost в explain, само выполнение запроса корректно.

Рабочая версия - время жрет сам планировщик. 7к партиций - это очень много. Об этом есть даже заметка в мануале (о чём там только нет заметок, но попробуй их заметь)
All constraints on all partitions of the master table are examined during constraint exclusion, so large numbers of partitions are likely to increase query planning time considerably. Partitioning using these techniques will work well with up to perhaps a hundred partitions; don't try to use many thousands of partitions.

https://www.postgresql.org/docs/9.4/static/ddl-par...

У postgresql партицирование сделано довольно странно и, вообще-то говоря, не предназначенными для этого средствами. Если у вас достаточно большая таблица, чтобы почувствовать бонусы от партицирования, то лучше ограничьтесь парой десятков разделов. Вот ещё статья тематическая есть: https://habrahabr.ru/post/273933/
Ответ написан
@shagguboy
https://www.postgresql.org/docs/9.5/static/ddl-par...
All constraints on all partitions of the master table are examined during constraint exclusion, so large numbers of partitions are likely to increase query planning time considerably. Partitioning using these techniques will work well with up to perhaps a hundred partitions; don't try to use many thousands of partitions.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы