【问题标题】:PostgreSQL: Index the day part of a timestampPostgreSQL:索引时间戳的日期部分
【发布时间】:2016-03-21 11:31:36
【问题描述】:

考虑下表:

       Column       |           Type           |
--------------------+--------------------------+
 id                 | bigint                   |
 creation_time      | timestamp with time zone |
...

像下面这样的查询(更不用说更复杂的 JOIN)需要相当长的时间,因为它们需要为每个项目计算 creation_time::DATE:

SELECT creation_time::DATE, COUNT(*) FROM items GROUP BY 1;

如何在时间戳的日期部分创建索引 - creation_time::DATE

我试过了:

  • CREATE INDEX items_day_of_creation_idx ON items (creation_time)::date;
  • CREATE INDEX items_day_of_creation_idx ON items (creation_time::date);

但两者都失败了:

ERROR:  syntax error at or near "::"

【问题讨论】:

    标签: postgresql date indexing


    【解决方案1】:

    当您在表达式上创建索引时,必须将表达式放在括号之间(除了围绕列/表达式列表的括号:

    CREATE INDEX items_day_of_creation_idx ON items ( (creation_time::date) );
    

    【讨论】:

    • 谢谢。现在我得到ERROR: functions in index expression must be marked IMMUTABLE。有趣,因为日期的日期部分是不可变的。
    • @AdamMatan:啊,我忽略了数据类型。 timestamp with time zonedate 的转换不是“不可变的”(因为它取决于时区)。这只有在您使用 timestamp without time zone 时才有效
    • 有什么方法可以在索引中进行转换?
    • @AdamMatan:以前有人问过这个问题。参见例如这里:stackoverflow.com/q/5973030/330315
    • 谢谢,会参考那个。
    【解决方案2】:

    这行得通,但我注意到使用表达式将时间戳转换为日期的索引比时间戳上的索引使用了更多的磁盘空间 (~15%-20%)。

    我希望通过 8 字节时间戳在 4 字节日期上构建索引时减少磁盘空间,但似乎情况并非如此,因为 8 字节似乎是索引中元素的最低公分母。所以,磁盘使用更差,查询性能差不多,所以我放弃了这种方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 2022-10-07
      • 2013-05-26
      • 2014-05-22
      • 1970-01-01
      相关资源
      最近更新 更多