Запрос postgresql медленно избегает использования функции - PullRequest
1 голос
/ 06 мая 2019

https://planchecker.cfapps.io/plan/Edo2MMbv

EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) 
SELECT COUNT(*) AS "__count" 
FROM "juliet" 
WHERE ("juliet"."whiskey" IN ('F') AND "juliet"."three" <= '2001-04-30')

есть индекс для этого поля juliet.three, как я могу убедиться, что этот запрос использует индекс?

скажем, в таблице 10N строки этот запрос возвращает 3N строк, так что считается 30% большой таблицы.

виски - это поле перечисления, которое хранится как поле char без индекса.Может быть, это проблема, я не уверен, что проблема в поле char или поле даты.

размер таблицы составляет порядка миллионов.

Также я получил предупреждениекак это: WARNING: Filter using function | Check if function can be avoided

как я могу избежать функций?это возможно?

Ответы [ 3 ]

2 голосов
/ 06 мая 2019

Postgres имеет хороший оптимизатор и выбирает наиболее оптимизированный план выполнения, основываясь на информации, которую он знает, и правилах, встроенных в оптимизатор базы данных.Для этого запроса ваш лучший индекс - juliet(whiskey, three).

Это закрывающий индекс для запроса, поэтому ему не требуется доступ к строкам данных.Кроме того, нужно сканировать только 30% индекса.

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

1 голос
/ 06 мая 2019

Ожидается, что запрос, который читает 3 миллиона строк, будет медленным.Я полагаю, что это для автономного процесса, поскольку использование его для онлайн-приложения вызывает проблемы.

Даже если то, что говорит @LaurenAlbe, возможно, я предполагаю, что принудительное использование индекса может на самом деле замедлить ваш запрос, чем использованиепоследовательное сканирование.

Единственное использование индекса, которое я вижу, - это то, что говорит @GordonLinoff: использование его для "индекса покрытия".

Но ... почему вы хотите использовать индекс впервое место?Любой запрос, который читает более 5% строк таблицы, обычно эффективно выполняется с использованием последовательного сканирования.

1 голос
/ 06 мая 2019

Если запрос действительно возвращает 30% таблицы, то PostgreSQL, вероятно, выбирает самый быстрый путь доступа, когда он использует последовательное сканирование.

Вы можете попробовать

SET enable_seqscan = off;

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

...