#postgresql #indexing
Вопрос:
my_table
включает в себя:
user_id | character varying | | not null |
epic_id | text | | not null |
"IDX_user" UNIQUE, btree ("user_id") WHERE status < 101
"IDX_epic" UNIQUE, btree ("epic_id") WHERE status < 101
Проблемный запрос
EXPLAIN ANALYZE SELECT * FROM my_table WHERE "epic_id" = 'asdf' and "status" < 101 LIMIT 1;
Limit (cost=0.28..8.29 rows=1 width=276) (actual time=0.230..0.231 rows=0 loops=1)
-> Index Scan using "IDX_user" on my_table (cost=0.28..8.29 rows=1 width=276) (actual time=0.229..0.230 rows=0 loops=1)
Filter: ("epic_id" = 'asdf'::text)
Rows Removed by Filter: 273
Planning Time: 0.122 ms
Execution Time: 0.248 ms
Есть совершенно хороший IDX_epic
. Почему мы используем IDX_user
, проходя 100 строк и потенциально вызывая раздражающие блокировки, когда это используется в транзакции?
Забавные Лакомые Кусочки
SET random_page_cost=1
не помогает, как рекомендовали другие сообщения stackoverflow- На локальном он использует правильный индекс! В локальной сети всего 90 строк с
status < 101
- При выполнении внутреннего объединения
"epic_id" = table.random_column
план действительно используетсяIDX_epic
. "user_id"
и"epic_id"
разные типы, но из того, что я прочитал, разница междуtext
иcharacter varying
близка к 0.- Согласно
pg_stat_all_indexes
,IDX_epic
имеетidx_scan
9 баллов, что подтверждает, что он не используется, кроме как для моих тестов.
Комментарии:
1. Ты побежал
VACUUM ANALYZE
первым?2. Вы провели недавний анализ (или вакуумный анализ) производственных таблиц?
3. Это закончилось тем, что я все исправил, спасибо >.>
Ответ №1:
Почему epicId находится в кавычках, а статус-нет? Также вы должны использовать LIKE как в epicId LIKE 'asdf'
для сравнения значений столбцов со строками.
Комментарии:
1. Postgres не чувствителен к регистру, поэтому он преобразуется
epicId
без кавычек вepicid
столбец и не может найти его.LIKE
по — прежнему использует неправильный индекс.2. мне кажется, что тогда проще, чтобы ваше имя столбца соответствовало соглашению об именовании змеиного случая и повторяло попытку
3. Ладно, теперь это дело змеи.
Ответ №2:
VACUUM ANALYZE
решил проблему- ANALYZE
один, скорее всего, решил бы ее.