Мои запросы очень медленно, когда я добавляю limit 1
.Запрос PostgreSQL очень медленный с ограничением 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 минут)
Этот запрос очень медленный, если для данного объектаID нет значений (это быстро, если есть результаты). Если удалить предел он говорит мне почти мгновенно, что нет никаких результатов:
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 555 строк и 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)
В целом я полагаю, что он должен делать с планировщиком делает неверные предположения о затратах на exectution и поэтому выбирает для более медленный план выполнения.
Это настоящая причина? Есть ли решение для этого?
Для случая с «пределом 1» вы имели в виду сканирование таблицы? Вы написали индексное сканирование – harmic
@harmic: OP имеет индексное сканирование там ... не обязательно всей таблицы, но, конечно, гораздо больше, чем то, что думал PG. –
Вы правы! Я только читаю текст OP, где он сказал, что не использует индекс. Но он выбирает сканировать индекс метки времени; странный выбор – harmic