Как я знаю, если какой-либо индекс используется в запросе |PostgreSQL 11? - PullRequest
0 голосов
/ 07 декабря 2018

Я немного растерялся и мне нужен совет.Я использую PostgreSQL 11 базу данных.У меня есть такой довольно простой оператор SQL:

SELECT DISTINCT "CITY", "AREA", "REGION"
    FROM youtube
WHERE
    "CITY" IS NOT NULL
AND
    "AREA" IS NOT NULL
AND
    "REGION" IS NOT NULL

youtube таблица, которую я использую в операторе SQL, имеет 25 миллионов записей.Я думаю, именно поэтому запрос занимает 15-17 секунд для завершения.Для веб-проекта, где я использую этот запрос, это слишком долго.Я пытаюсь ускорить запрос.

Я создаю такой индекс для таблицы YouTube:

CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");

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

ОБЪЯСНИТЬ АНАЛИЗ return: enter image description here

Ответы [ 2 ]

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

Я думаю, что вы можете использовать индекс по этому вопросу.Что-то вроде:

SELECT "CITY", "AREA", "REGION"
FROM (SELECT DISTINCT ON ("CITY", "AREA", "REGION") "CITY", "AREA", "REGION"
      FROM youtube
      ORDER BY "CITY", "AREA", "REGION"
     ) car
WHERE "CITY" IS NOT NULL AND
      "AREA" IS NOT NULL AND
      "REGION" IS NOT NULL;

Это должно использовать индекс ("CITY", "AREA", "REGION") для SELECT DISTINCT - что, вероятно, является дорогостоящей операцией для этого запроса.

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

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

Вы сами ответили на вопрос в названии, набрав EXPLAIN.План запроса показывает, какие индексы используются и как.Подробнее см. Главу «Использование EXPLAIN» в руководстве.

Что касается того, почему в запросе используется последовательное сканирование без индексов: 25 миллионов строк, 2992781 rows removed.Вы получаете 24709900 rows, это почти все строки.

Это никогда не будет быстрым.
Это никогда не будет использовать индекс.

Использование индекса имеет смысл толькодля небольшой доли всех рядов.В противном случае это просто добавит дополнительную стоимость.В зависимости от ряда сопутствующих факторов планировщик запросов Postgres начинает рассматривать индекс btree примерно для 5% всех строк или меньше.Связанный:

Хорошо, если строки таблицы значительно шире, чем три столбцав вашем списке SELECT частичный , охватывающий индекс , может несколько помочь, если вы получите из него только сканирование по индексу.Опять же, необходимо выполнить некоторые предварительные условия.И каждый индекс также имеет затраты на хранение и обслуживание.

В сторону: заявленный комментарий, значения NULL не могут быть проиндексированы.Это неверно, значения NULL могут быть проиндексированы.Не так эффективно, как другие ценности, но не имеет большого значения.Также не имеет отношения к делу под рукой.

...