当我添加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分钟的查询)
如果给定objectID的值没有结果,这个查询非常缓慢(如果有结果则很快)。 如果我移除限制,它会立即告诉我没有结果:
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)
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)
总的来说,我认为这与规划者对执行成本做出错误假设有关,因此选择了更慢的执行计划。
这是真正的原因吗?是否有解决方法?