6

type の「made_at」列を持つ postgres テーブル ENTRIES を用意しますtimestamp without time zone

そのテーブルには、その列と別の列 (USER_ID、外部キー) の両方に btree インデックスがあります。

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

ご覧のとおり、日付は「日」で切り捨てられています。この方法で構築されたインデックスの合計サイズは 130 MB です。ENTRIES テーブルには 4,000,000 行あります。

質問: 時間を秒単位まで考慮した場合、インデックスのサイズはどのように見積もればよいですか? 基本的に、タイムスタンプを日ではなく秒で切り捨てます (簡単にできるはずです)。

4

1 に答える 1

6

興味深い質問です!私の調査によると、それらは同じサイズになります。

私の直感では、PostgreSQL のタイムスタンプ型は固定サイズ ( 8 バイト) であるため、2 つのインデックスのサイズに違いはないはずであり、truncate 関数は適切な数の最下位時間ビットを単純にゼロにすると仮定しました。しかし、いくつかの事実で自分の推測を裏付けるほうがよいと考えました。

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)
于 2013-08-26T22:05:05.870 に答える