Мои запросы становятся очень медленными, когда я добавляю limit 1
.
У меня есть таблица object_values
с отметками времени для объектов:
timestamp | objectID | value
--------------------------------
2014-01-27| 234 | ksghdf
Для каждого объекта я хочу получить последнее значение:
SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC LIMIT 1;
(я отменил запрос после более 10 минут)
Этот запрос очень медленный, если для данного идентификатора объекта нет значений (он быстрый, если есть результаты). Если я удаляю предел, он почти мгновенно сообщает мне, что результатов нет:
SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC;
...
Time: 0.463 ms
Объяснение показывает, что запрос без ограничения использует индекс, где в качестве запроса с limit 1
не используется индекса:
Медленный запрос:
explain SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC limit 1;
QUERY PLAN`
----------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..2350.44 rows=1 width=126)
-> Index Scan Backward using object_values_timestamp on object_values (cost=0.00..3995743.59 rows=1700 width=126)
Filter: (objectID = 53708)`
Быстрый запрос:
explain SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Sort (cost=6540.86..6545.11 rows=1700 width=126)
Sort Key: timestamp
-> Index Scan using object_values_objectID on working_hours_t (cost=0.00..6449.65 rows=1700 width=126)
Index Cond: (objectID = 53708)
Таблица содержит 44 884 559 строк и 66,762 различных идентификаторов объектов.
У меня есть отдельные индексы для обоих полей: timestamp
и objectID
.
Я сделал vacuum analyze
для таблицы и переиндексировал таблицу.
Кроме того, медленный запрос становится быстрым, когда я устанавливаю ограничение на 3 или выше:
explain SELECT * FROM object_values WHERE (objectID = 53708) ORDER BY timestamp DESC limit 3;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Limit (cost=6471.62..6471.63 rows=3 width=126)
-> Sort (cost=6471.62..6475.87 rows=1700 width=126)
Sort Key: timestamp
-> Index Scan using object_values_objectID on object_values (cost=0.00..6449.65 rows=1700 width=126)
Index Cond: (objectID = 53708)
В общем, я предполагаю, что это связано с тем, что планировщик делает неверные предположения о затратах на оплату и поэтому выбирает для более медленный план выполнения.
1125 Это реальная причина? Есть ли решение для этого?