Как ускорить запрос с помощью DISTINCT в PostgreSQL? - PullRequest
0 голосов
/ 06 декабря 2018

Как видите, у меня довольно простой оператор SQL:

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

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

Я создаю индекс, как показано ниже, но мой запрос выше по-прежнему требует того же времени для завершения.Что я сделал не так?Кстати, лучше ли использовать «разбиение» в моем случае?

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

EXPLAIN возвращает:

Unique (cost=5984116.71..6111107.27 rows=96410 width=32)
-> Sort (cost=5984116.71..6047611.99 rows=25398112 width=32)
   Sort Key: ((((("CITY" || ' | '::text) || "AREA") || ' | '::text) || "REGION"))
   -> Seq Scan on youtube (cost=0.00..1037365.24 rows=25398112 width=32) 

@ george-joseph QUERY PLAN вашего скрипта:

enter image description here

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Здесь не помогут ни индекс, ни разбиение.

Поскольку city, area и region (вероятно) тесно связаны, число строк результатов будет намного меньше, чем оценки PostgreSQLпотому что он предполагает, что столбцы независимы друг от друга.

Таким образом, вы должны создать расширенную статистику для этих столбцов, новая функция, представленная в PostgreSQL v10:

CREATE STATISTICS youtube_stats (ndistinct)
   ON "CITY", "AREA", "REGION" FROM youtube;

ANALYZE youtube;

Теперь у PostgreSQL лучшепредставление о том, сколько существует различных групп.

Затем выделите запросу много памяти, чтобы он мог получить хэш со всеми этими группами в память.Тогда он может использовать агрегат хешей вместо сортировки строк:

SET work_mem = '1GB';

Вам может не понадобиться столько памяти;Эксперимент, чтобы найти более разумный предел.

Затем попробуйте запрос из ответа Джорджа Джозефа:

SELECT x."CITY" || ' | '  || x."AREA" || ' | ' || x."REGION" AS location
FROM (SELECT DISTINCT "CITY", "AREA", "REGION"
      FROM youtube) AS x;
0 голосов
/ 06 декабря 2018

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

SELECT DISTINCT ON (city, area, region) "CITY" || ' | '  || "AREA" || ' | ' || "REGION") AS LOCATION
FROM youtube
ORDER BY city, area, region;

Для этого можно воспользоваться индексом (city, area, region).

0 голосов
/ 06 декабря 2018

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

SELECT x.city || ' | '  || x.area || ' | ' || x.region
FROM (SELECT DISTINCT city, area, region
      FROM youtube) x 
...