un1t
@un1t

Почему DISTINCT ON так медленно выполняется?

Табличка 931 263 записей.
Запрос
select distinct on (o.group_id) o.id group_id from offers o limit 10;

выполняется больше чем пол секунды. Причем есть индекс по group_id.

Структура таблицы:
# \d+ offers;
                                                        Table "public.offers"
    Column    |          Type           |                      Modifiers                      | Storage  | Stats target | Description 
--------------+-------------------------+-----------------------------------------------------+----------+--------------+-------------
 id           | integer                 | not null default nextval('offers_id_seq'::regclass) | plain    |              | 
 name         | character varying(400)  | not null                                            | extended |              | 
 group_id     | integer                 |                                                     | plain    |              | 
Indexes:
    "offers_pkey" PRIMARY KEY, btree (id)
    "offers_group_id_e0c51f8a" btree (group_id)


EXPLAIN ANALYZE

# explain analyze select distinct on (o.group_id) o.id group_id from offers o limit 10;
-[ RECORD 1 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Limit  (cost=0.42..59572.55 rows=10 width=8) (actual time=0.089..566.879 rows=1 loops=1)
-[ RECORD 2 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |   ->  Unique  (cost=0.42..1191442.91 rows=200 width=8) (actual time=0.087..566.876 rows=1 loops=1)
-[ RECORD 3 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |         ->  Index Scan using offers_group_id_e0c51f8a on offers o  (cost=0.42..1189221.41 rows=888599 width=8) (actual time=0.085..529.775 rows=931263 loops=1)
-[ RECORD 4 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Planning time: 0.137 ms
-[ RECORD 5 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Execution time: 566.925 ms


Как можно ускорить?
  • Вопрос задан
  • 734 просмотра
Пригласить эксперта
Ответы на вопрос 2
Melkij
@Melkij
PostgreSQL DBA
Ускорить можно вот такой милой рекурсивной cte'шкой: https://wiki.postgresql.org/wiki/Loose_indexscan
Нативно pg пока не умеет loose indexscan. Поэтому distinct читает все элементы дерева вместо поиска следующего большего элемента.
Ответ написан
sergey-gornostaev
@sergey-gornostaev Куратор тега PostgreSQL
Седой и строгий
Использовать группировку по требующему уникальности полю
select min(id), group_id from offers group by group_id;

В моём случае это примерно в 6.5 раз быстрее.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы