pgsql-performance - отличный список рассылки для вопросов такого рода.
Кажется, у вас есть две проблемы:
1) Вы хотите иметь возможность индексировать updated_on, но если вы это сделаете, PostgreSQL выбирает неправильный план.
Мое первое сомнение заключается в том, что PostgreSQL переоценивает количество кортежей, соответствующих предикату "(responses.contest_id = 17469) AND (user_id is not null)
". Если postgres сначала использует этот предикат, он должен позже отсортировать значения для реализации ORDER BY. Вы говорите, что это соответствует 1000 кортежей; если postgresql считает, что он соответствует 100000, возможно, он считает, что сканирование по порядку с использованием индекса updated_on будет дешевле. Другим фактором может быть ваша конфигурация: если значение work_mem
установлено на низком уровне, может показаться, что сортировка обходится дороже, чем она есть.
Вам действительно нужно показать вывод EXPLAIN ANALYZE медленного запроса, чтобы мы могли понять, почему он может выбирать сканирование индекса для updated_on
.
2) Даже если он не проиндексирован, иногда требуется некоторое время для выполнения, но вы не знаете почему, потому что, если вы запускаете его вручную, он работает нормально.
Используйте модуль auto_explain
contrib, новый с 8.4. Это позволяет вам регистрировать вывод EXPLAIN ANALYZE
запросов, которые занимают слишком много времени. Простая регистрация запроса ставит вас именно в ту проблему, с которой вы сейчас сталкиваетесь: каждый раз, когда вы запускаете запрос, это быстро.