@nurzhannogerbek

Как ускорить запрос с DISTINCT в PostgreSQL?

Здравствуйте, товарищи! Помогите пожалуйста разобраться.

Есть довольно простой скрипт. Выглядит он следующим образом:

SELECT DISTINCT("CITY" || ' | '  || "AREA" || ' | ' || "REGION") AS LOCATION FROM youtube


Таблица youtube, которая используется в запросе состоит из 25 миллионов записей. Каждые 5 минут таблица пополняется новыми данными. Данный скрипт отрабатывается очень долго (~50 секунд).

EXPLAIN ANALYZE возвращает следующее:
5c08ad6f72b89825570616.png

Я пытаюсь ускорить запрос. Добавил индекс следующим образом:

CREATE INDEX location_index ON youtube ("CITY", "AREA", "REGION")


После добавление индекса запрос не ускорился. Возможно в самом запросе нужно явно указать, чтобы использовался индекс. Как это сделать в PostgreSQL? Знаю, что к примеру в MySQL для этого используется FORCE INDEX. Есть ли вообще смысл в индексе или партиционирование раз в запросе не используется WHERE.
  • Вопрос задан
  • 1895 просмотров
Решения вопроса 2
Melkij
@Melkij
PostgreSQL DBA
Планировщик Postgresql на данный момент не умеет loose index scan. Поэтому планировщик вполне обоснованно со своей точки зрения выбирает не использовать какие-либо индексы.

Поэтому если необходим именно distinct по не очень селективному полю - то эффективнее объяснить планировщику что от него хотят руками: https://wiki.postgresql.org/wiki/Loose_indexscan

Вам же скорее необходимо менять схему хранения данных.

Возможно в самом запросе нужно явно указать, чтобы использовался индекс. Как это сделать в PostgreSQL?Возможно в самом запросе нужно явно указать, чтобы использовался индекс. Как это сделать в PostgreSQL?

Никак. Сообщество сознательно PostgreSQL отказывается добавлять какие-либо хинты планировщика, предпочитая узнавать об ошибках планировщика как о багах и по возможности их исправлять.
Ответ написан
@x_shader
Oracle & Coffee
Должно помочь избавление от конкатенации.

SELECT DISTINCT CITY, AREA, REGION FROM youtube
или
SELECT CITY,  AREA, REGION
FROM youtube
GROUP BY CITY,  AREA, REGION


Если сильно нужно получать именно конкатенированный результат, то подзапрос все-равно будет быстрее
SELECT  "CITY" || ' | '  || "AREA" || ' | ' || "REGION" FROM (
    SELECT CITY,  AREA, REGION
    FROM youtube
    GROUP BY CITY,  AREA, REGION) t
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sergey-gornostaev
@sergey-gornostaev Куратор тега PostgreSQL
Седой и строгий
Составной индекс по полям - это не то же самое, что индекс по конкатенированному значению этих полей. Соответствующий индекс должен создаваться так

CREATE INDEX youtube_location_idx ON youtube ((CITY || ' | '  || AREA || ' | ' || REGION));

Но ещё лучше пересмотреть подход к структуре таблицы и запросов.
Ответ написан
Ваш ответ на вопрос

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

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