postgresql 表大小比Postgres中的实际数据大得多

fykwrbwg  于 2023-04-05  发布在  PostgreSQL
关注(0)|答案(1)|浏览(261)

我有一个表,让我们称之为Roads(更改为不显示公司的东西)。此表存储地点之间的非规范化道路,具有以下模式:

CREATE TABLE public.roads (
    id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
    'from' varchar NOT NULL,
    'to' varchar NOT NULL,
    updated_at timestamp NOT NULL,
    metadata_id int8 NULL,
    CONSTRAINT roads_pkey PRIMARY KEY (id),
    CONSTRAINT roads_from_to_key UNIQUE (from, to)
)
WITH (
    autovacuum_vacuum_cost_delay=0,
    autovacuum_vacuum_cost_limit=1500
);
CREATE INDEX from_idx ON public.roads USING btree ('from');
CREATE INDEX updated_at_idx ON public.roads USING btree (updated_at);
CREATE INDEX to_idx ON public.roads USING btree ('to');

由于查询时的性能原因,位置被反规范化。
如果我将所有数据导出为CSV,则文件仅为6MB。但在DB上,此表为12GB。
正如你所看到的,我添加了自动真空调整,试图解决这个问题,但它没有帮助。
使用模式是大量的更新,最终改变了时间戳。所以我认为autovacuum没有跟上一定有问题。这是一个非常大的db,autovacuum可能很慢,但这太多了。
这是为什么呢?有什么建议吗?不可能指数这么大。

iyr7buue

iyr7buue1#

这样的表通常是CSV文件大小的两倍。
首先,数据是以8kB的块组织的。有一个块的头部,一些空间通常必须保持空白。还有更多的开销:每一行都有一个23字节的标题。这将占大部分的开销。除此之外,行和许多列必须对齐到特定的内存边界,这导致在列之前和列之间填充。有关详细信息,请参阅the documentation
再加上这三个索引,可以轻松地将空间需求增加一倍。
您可以使用pg_relation_size()来找出磁盘上索引的大小。使用pg_table_size()来找出没有索引的表的大小。

相关问题