【问题标题】:Fastest way to see what unique dates are in a table's timestamp field?查看表的时间戳字段中的唯一日期的最快方法是什么?
【发布时间】:2011-08-27 15:19:26
【问题描述】:

我有一个包含数十亿行的表。 “记录”字段上有每日分区,是“没有时区的时间戳”。我想知道表中当前有哪些日期。我知道我可以这样做:

SELECT recorded::date
FROM table
GROUP BY 1;

理想情况下应该可行,但对此的解释相当高,并且表明需要相当长的时间才能工作......如果这是我能做的最好的,我可以接受(我们可以密切关注数据),但我想知道是否有更有效的方法来做到这一点,因为我每天都有分区?

【问题讨论】:

    标签: postgresql greenplum


    【解决方案1】:

    您可以像这样创建索引:

    create index your_index_name
    on table (date_trunc('day', recorded))
    

    在我的测试中,PostgreSQL 9.something 在添加索引之前使用了顺序扫描,在简单地为“记录”列建立索引之后进行顺序扫描,并在使用 date_trunc() 对其进行索引之后进行索引扫描。选择一天的行需要 66 毫秒(不使用索引),68 毫秒(使用普通索引)和 13 毫秒(使用 date_trunc())。

    拥有数十亿行,预计创建该索引需要几分钟时间。 (咳嗽)

    【讨论】:

      【解决方案2】:

      这里有一个非常相似的帖子:

      Slow select distinct query on postgres

      如果您知道最小/最大日期,则最好查询日期列表,而不是对整个表进行 seq 扫描。假设你有一个记录的索引,看起来像这样的东西应该更快:

      with days as (
      select date_trunc('day', min(recorded))::date + k * interval '1 day' as day
      from records,
           generate_series(0,
                          (select date_trunc('day', max(recorded))::date
                                  - date_trunc('day', min(recorded)::date
                          from records
           )) as k
      )
      select day
      from days
      where exists (
            select 1
            from records
            where day <= recorded and recorded < day + interval '1 day'
            );
      

      可能需要对上述查询进行一些调整,但总体思路是:对索引字段执行数千次子查询/索引扫描比对数十亿次进行 seq 扫描更快行并聚合它们以识别不同的日期。

      【讨论】:

      • 如果表每天分区一个分区,你甚至不需要日期索引,因为约束排除会选择正确的表,并且从表中读取的第一行将满足存在。
      猜你喜欢
      • 2020-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2019-01-15
      • 2010-12-14
      相关资源
      最近更新 更多