我在Postgres数据库中有一个表,每10分钟存储一次值。我现在在该表中有很多记录(我不想删除旧的记录)。基本上,该行包含值和时间戳。我的SQL请求没有优化,因为它似乎遍历整个表...
SELECT value, date FROM measures order by date desc limit 1
我还尝试在日期添加过滤器,例如:
SELECT value, date FROM measures WHERE date > date '2011-10-20' order by date desc limit 1
(当然日期是动态的)。但同样的事情......
是否需要索引或者可以优化查询?
答案 0 :(得分:2)
首先,您不应将时间戳列命名为 date
。一个'date' is not a 'timestamp'。此外,虽然它在PostgreSQL中是允许的,但它在任何SQL标准中都是reserved word。 (我会坚持date
为了这个答案的目的,但是)
除此之外,像Tommy建议的index on an expression和WHERE
条款不需要。 (date(created_at)
)。 普通B树索引和没有WHERE
子句的查询可以使作业更简单,更快捷。
CREATE INDEX measures_date_idx ON measures(date);
然后您的查询将按原样运行,快速闪电。 B树索引可用于升序和降序排序顺序同样有效。阅读手册中 Indexes and ORDER BY 的章节 - 涵盖了您需要知道的大部分内容。
如果您的表格非常庞大并且您担心索引大小,那么可以使用 partial index 来大幅减小尺寸。像这样:
CREATE INDEX measures_date_idx ON measures(date)
WHERE date > '2011-10-20 00:00:00'::timestamp;
然后,您的查询必须包含与用于部分索引的完全相同的WHERE
子句。像这样:
SELECT value, date
FROM measures
WHERE date > '2011-10-20 00:00:00'::timestamp
ORDER BY date DESC
LIMIT 1;
答案 1 :(得分:1)
首先关闭 - 动态+1。你是对的,你的查询变得越来越慢,因为没有索引,你每次查询一个值时都在进行全表扫描。我不是一个强大的postgres数据库用户,但看起来你可以在你的日期字段上放置一个索引(因为这是你主要查询的内容)。
另一个常见的例子是查找给定日期的行,其中 我们已将时间戳存储在日期时间字段中,但希望通过a找到它们 日期铸造价值。像
这样的索引
CREATE INDEX articles_day ON articles ( date(created_at) )
可以由包含
的查询使用
WHERE date(articles.created_at) = date('2011-03-07').
根据您的具体情况,您可能会发现该文章中的其他一些信息也很有趣。