2

我有一张有数十亿行的表。“记录”字段有每日分区,是“无时区的时间戳”。我想知道表中当前有哪些日期。我知道我可以做类似的事情:

SELECT recorded::date
FROM table
GROUP BY 1;

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

4

2 回答 2

2

您可以像这样创建索引:

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

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

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

于 2011-05-18T00:36:32.813 回答
1

这里有一个非常相似的线程:

在 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 扫描更快,并且聚合它们以识别不同的日期。

于 2011-05-18T01:58:01.423 回答