Порядок разбиения Postgres по производительности - PullRequest
1 голос
/ 07 июня 2011

Я использую секционированную таблицу postgres, следуя документации , используя правила, используя схему секционирования, основанную на диапазонах дат (мой столбец дат - целое число эпох)

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

Во-первых, некоторые настройки, чтобы заставить postgres делать то, что я хочу: SET constraint_exclusion = вкл; SET enable_seqscan = off;

Запрос на один раздел работает:

explain (SELECT * FROM urls_0 ORDER BY date_created ASC  LIMIT 1);
Limit  (cost=0.00..0.05 rows=1 width=38)
  ->  Index Scan using urls_date_created_idx_0 on urls_0  (cost=0.00..436.68 rows=8099 width=38)

Тем не менее, один и тот же запрос для всей таблицы является следующим сканированием:

explain (SELECT * FROM urls ORDER BY date_created ASC  LIMIT 1);
Limit  (cost=50000000274.88..50000000274.89 rows=1 width=51)
   ->  Sort  (cost=50000000274.88..50000000302.03 rows=10859 width=51)
         Sort Key: public.urls.date_created
         ->  Result  (cost=10000000000.00..50000000220.59 rows=10859 width=51)
               ->  Append  (cost=10000000000.00..50000000220.59 rows=10859 width=51)
                     ->  Seq Scan on urls  (cost=10000000000.00..10000000016.90 rows=690 width=88)
                     ->  Seq Scan on urls_15133 urls  (cost=10000000000.00..10000000016.90 rows=690 width=88)
                     ->  Seq Scan on urls_15132 urls  (cost=10000000000.00..10000000016.90 rows=690 width=88)
                     ->  Seq Scan on urls_15131 urls  (cost=10000000000.00..10000000016.90 rows=690 width=88)
                     ->  Seq Scan on urls_0 urls  (cost=10000000000.00..10000000152.99 rows=8099 width=38)

Наконец, поиск по date_created корректно работает с исключениями из противопоказаний и сканированием индекса:

explain (SELECT * FROM urls where date_created = 1212)
Result  (cost=10000000000.00..10000000052.75 rows=23 width=45)
   ->  Append  (cost=10000000000.00..10000000052.75 rows=23 width=45)
         ->  Seq Scan on urls  (cost=10000000000.00..10000000018.62 rows=3 width=88)
               Filter: (date_created = 1212)
         ->  Index Scan using urls_date_created_idx_0 on urls_0 urls  (cost=0.00..34.12 rows=20 width=38)
               Index Cond: (date_created = 1212)

Кто-нибудь знает, как использовать разбиение, чтобы этот тип запроса использовал сканирование индекса?

1 Ответ

4 голосов
/ 07 июня 2011

Postgresql 9.1 знает, как оптимизировать это "из коробки".

В 9.0 или более ранних версиях вам необходимо разложить запрос вручную, объединяя каждый из подзапросов по отдельности с их собственным оператором order by / limit.

...