postgres - 估计timestamp列的索引大小

时间:2013-08-26 20:57:31

标签: postgresql indexing

有一个postgres表,ENTRIES,带有timestamp without time zone类型的'made_at'列。

该表在该列和另一列(USER_ID,外键)上都有一个btree索引:

btree (user_id, date_trunc('day'::text, made_at))

如您所见,日期在“日期”被截断。以这种方式构造的索引的总大小为130 MB - 在ENTRIES表中有4,000,000行。

问题:如果我要关心时间到第二个,我如何估计指数的大小?基本上,在第二天而不是一天截断时间戳(我希望这应该很容易)。

1 个答案:

答案 0 :(得分:4)

有趣的问题!根据我的调查,它们的大小相同。

我的直觉告诉我,两个索引的大小之间应该没有区别,因为PostgreSQL中的时间戳类型具有固定大小(8 bytes),我认为截断函数只是将相应的数字清零最重要的时间位,但我认为我最好用一些事实支持我的猜测。

我在heroku PostgreSQL上创建了一个免费的dev数据库,并生成了一个包含4M随机时间戳的表,截断为日期和秒值,如下所示:

test_db=> SELECT * INTO ts_test FROM 
                        (SELECT id, 
                                ts, 
                                date_trunc('day', ts) AS trunc_day, 
                                date_trunc('second', ts) AS trunc_s 
                         FROM (select generate_series(1, 4000000) AS id, 
                               now() - '1 year'::interval * round(random() * 1000) AS ts) AS sub) 
                         AS subq;
SELECT 4000000

test_db=> create index ix_day_trunc on ts_test (id, trunc_day);
CREATE INDEX
test_db=> create index ix_second_trunc on ts_test (id, trunc_s);
CREATE INDEX
test_db=> \d ts_test
           Table "public.ts_test"
  Column   |           Type           | Modifiers 
-----------+--------------------------+-----------
 id        | integer                  | 
 ts        | timestamp with time zone | 
 trunc_day | timestamp with time zone | 
 trunc_s   | timestamp with time zone | 
Indexes:
    "ix_day_trunc" btree (id, trunc_day)
    "ix_second_trunc" btree (id, trunc_s)

test_db=> SELECT pg_size_pretty(pg_relation_size('ix_day_trunc'));
          pg_size_pretty 
          ----------------
          120  MB
          (1 row)

test_db=> SELECT pg_size_pretty(pg_relation_size('ix_second_trunc'));
          pg_size_pretty 
          ----------------
          120 MB
          (1 row)