【问题标题】:It's getting longer to get the last value of my table获得我表的最后一个值的时间越来越长
【发布时间】:2011-10-21 05:07:31
【问题描述】:

我的 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

(当然日期是动态的)。但同样的事情......

是否需要索引或者可以优化查询?

【问题讨论】:

    标签: postgresql datetime indexing


    【解决方案1】:

    首先,您不应将时间戳列命名为 date。一个'date' is not a 'timestamp'。此外,虽然它在 PostgreSQL 中是允许的,但在任何 SQL 标准中它都是 reserved word。 (不过,出于此答案的目的,我会坚持使用date

    除此之外,不需要像 Tommy 建议的那样使用 index on an expressionWHERE 子句。 (date(created_at))。 普通的 B 树索引和不带 WHERE 子句的查询可以更简单、更快速地完成工作。

    CREATE INDEX measures_date_idx ON measures(date);
    

    然后您的查询将按原样运行,速度很快。 B-tree 索引可用于升序和降序排序同样有效。阅读手册中关于 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;
    

    【讨论】:

      【解决方案2】:

      首先 - 动态 +1。你是对的,你的查询变得越来越慢,因为没有索引,你每次查询一个值时都会进行全表扫描。我不是一个强大的 postgres DB 用户,但看起来你可以在你的日期字段上放置一个索引(因为这是你主要查询的内容)。

      From this article:

      另一个常见示例是查找给定日期的行,其中 我们已经在 datetime 字段中存储了时间戳,但希望通过 日期铸造值。像

      这样的索引
      CREATE INDEX articles_day ON articles ( date(created_at) )  
      

      可以被包含

      的查询使用
      WHERE date(articles.created_at) = date('2011-03-07').
      

      根据您的具体情况,您可能会在该文章中发现一些有趣的其他信息。

      【讨论】:

      • 感谢@tommy。在代码中,您的意思是 created_at 而不是 published_at,不是吗?
      • 抱歉 - 这是我链接到的文章中的复制意大利面 :)
      猜你喜欢
      • 1970-01-01
      • 2018-01-23
      • 1970-01-01
      • 2022-11-12
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多