【问题标题】:postgres - estimate index size for timestamp columnpostgres - 估计时间戳列的索引大小
【发布时间】:2023-03-21 00:38:01
【问题描述】:

有一个 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 行。

问题:如果我要注意时间到秒,我如何估计索引的大小?基本上,在秒而不是一天截断时间戳(应该很容易做到,我希望)。

【问题讨论】:

    标签: postgresql indexing


    【解决方案1】:

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

    我的直觉告诉我,你的两个索引的大小应该没有区别,因为 PostgreSQL 中的时间戳类型是固定大小的 (8 bytes),我认为 truncate 函数只是将适当数量的最小值归零重要的时间位,但我想我最好用一些事实来支持我的猜测。

    我在 heroku PostgreSQL 上创建了一个免费的开发数据库,​​并生成了一个包含 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)
    

    【讨论】:

    • 谢谢,感谢您的回答和示例。这很有趣——显然,我对如何构建数据库索引知之甚少;我假设由于树中的叶节点会有更多的错误、“桶”或“节点”,因此树的总大小也会大得多。或许你能指出我的想法有什么问题吗?谢谢!
    • 很难弄清楚你在想什么 :)。你为什么假设树中会有更多的叶节点?无论列的内容如何,​​要索引的行数都是相同的。
    • 很公平 =) 我会尽力解释我的意思。我的直觉是这样的——如果有 1000 条消息,并且都在同一天,那么索引将毫无用处——因为很明显,所有记录到日期为止都具有相同的时间戳——所以索引无法帮助我们缩小个人记录。它们都在同一个“桶”中;它们都是同一个树节点上的叶子,不是吗?例如,如果我们按小时四舍五入,那么我们将有 24 个节点(假设一个合理的正态分布),并且实际的行悬挂在较小的束中 =)
    • Alex- 你提出了一个很好的观点。恐怕我不能权威地回答。正确答案可能取决于特定的 btree 实现细节。
    • 你应该担心你的列是否是 varchar 例如,在这种情况下索引大小取决于列大小
    猜你喜欢
    • 2020-12-24
    • 1970-01-01
    • 2019-11-08
    • 2020-04-07
    • 2010-09-09
    • 1970-01-01
    • 2013-08-21
    • 2010-09-15
    • 1970-01-01
    相关资源
    最近更新 更多