28

Consider the following table:

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

Queries like the following (let alone more complicated JOINs) takes quite a while, because they needs to calculate creation_time::DATE for each item:

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

How do I create an index on the day part of the timestamp - creation_time::DATE?

I have tried:

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

But both failed with:

ERROR:  syntax error at or near "::"

2 Answers 2

28

When you create an index on an expression that expression must be put between parentheses (in addition to the parentheses that surround the column/expression list:

CREATE INDEX items_day_of_creation_idx ON items ( (creation_time::date) );
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. Now I get ERROR: functions in index expression must be marked IMMUTABLE. Funny, because the day part of a date is as immutable as it gets.
@AdamMatan: ah, I overlooked the data type. The conversion of a timestamp with time zone to a date is not "immutable" (because it depends on the time zone). This would only work if you were using timestamp without time zone
Any way to make the conversion in the index?
@AdamMatan: this has been asked before. See e.g. here: stackoverflow.com/q/5973030/330315
Thanks, will refer to that one.
0

This worked, but I noticed that the index using an expression to cast a timestamp to a date used more disk space (~15%-20%) than an index on the timestamp.

I hoped for a disk space reduction in building an index on a 4 byte date over a 8 byte timestamp, but it seems that's not the case because 8 bytes seems to be the lowest common denominator for an element in the index. So, the disk use was worse, and the query performance was about the same, so I abandoned this approach.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.