A.c*_*A.c 3 postgresql datatypes storage database-size
我有一个关于我的数据库大小的简短问题。我需要在数据库中插入数据。在插入之前,需要进行一些计算。
关键是:从 50 mb 纯数据(~700,000 行),这导致 600 mb db 大小。这是12倍!我确定我在这里做错了什么。你能帮我缩小我的数据库的大小吗?数据库大小的来源是 web postgres 管理界面。
这是插入:
CREATE TYPE CUSTOMER_TYPE AS ENUM
('enum1', 'enum2', 'enum3', '...', 'enum15'); ## max lenght of enum names ~15
CREATE TABLE CUSTOMER(
CUSTOMER_ONE TEXT PRIMARY KEY NOT NULL, ## max 35 char String
ATTRIBUTE_ONE TEXT UNIQUE, ## max 35 char String
ATTRIBUTE_TWO TEXT UNIQUE, ## max 51 char String
ATTRIBUTE_THREE TEXT UNIQUE, ## max 52 char String
ATTRIBUTE_FOUR TEXT UNIQUE, ## max 64 char String
ATTRIBUTE_FIFE TEXT UNIQUE, ## 1-80 char String
CUSTOMER_TYPE PRIVATEKEYTYPE ## see enum
);
Run Code Online (Sandbox Code Playgroud)
我真的不需要那个枚举,因为我也可以插入它。枚举对数据库大小有影响吗?
有没有办法减小尺寸?是否有可能达到因子 x4(而不是 x12)?如果没有,如有必要,我可以删除一些列。
也许还有其他用于字符数据的 Postgres 数据类型?
在这里反馈后,我更新后的表格现在看起来像这样:
CREATE TABLE CUSTOMER(
CUSTOMER_ONE TEXT PRIMARY KEY NOT NULL, ## max 35 char String
ATTRIBUTE_ONE TEXT UNIQUE, ## max 35 char String
ATTRIBUTE_TWO TEXT, ## max 51 char String
ATTRIBUTE_THREE TEXT, ## max 52 char String
ATTRIBUTE_FOUR TEXT, ## max 64 char String
ATTRIBUTE_FIFE TEXT, ## 1-80 char String
CUSTOMER_TYPE PRIVATEKEYTYPE ## see enum
);
Run Code Online (Sandbox Code Playgroud)
之前:12x
现在:7x :)
还有更多可能的优化吗?(除了删除列?)也许其他数据类型使用更少的空间?
text
是纯文本的最佳类型。单独的文本值在内部占用大致相同(当然也取决于编码细节:UTF-8?)。在您的情况下,每个字段 1 个字节的小开销。看:
该enum
列对总大小的贡献很小。每行 4 个字节(real
内部数量)。枚举名称的长度实际上无关紧要,作为数据类型存储一次name
,因此最多为NAMEDATALEN
(通常为 63 个字符)。类型声明的开销最小。因此,ENUM列实际占用较少比在文本文件中的DB内部空间。
Postgres 存储有各种类型的开销,它必须是这样的。其中一些是一次性成本,另一些是与行数或关系等的比例。 有目录表(系统数据)、索引、关系、表统计、簿记数据等。
对于 50 MB 的原始文本数据来说,12 倍的大小似乎超过了平均值。但这真的取决于细节。许多小行有很多开销,很少有大行没有那么多,甚至可以压缩和更小。a_horse 已经指出了一个主要原因:6 个索引 - 其中一些显然也是不必要的。
表中的每一行都有一个占 23 个字节的元组头(加上对齐填充,通常为 24 个字节),列和元组之间可能有对齐填充,4 个字节用于项目标识符,每个数据页有一些开销(通常为 8kb 页面大小)。在您的情况下,每行大约 35 个字节。
每个索引元组都差不多(标头只有 8 个字节,但索引膨胀更多)。6 个索引,每个表行至少约 150 字节。加上每个文本列都保存两次,1x 表,1x 索引。并且 btree 索引以FILLFACTOR
90 的a 开头,因此所有内容都为 ~ + 10 %。
您的平均行大小约为 75 字节(50MB / 700000 - 假设“行”对应于行)。您的表和索引大约占用原始文本大小的 6 倍。剩下的就是上面提到的其他开销。
这一切都假设没有表膨胀(还)。一旦您使用数据库(更新、删除、事务回滚等),就会有死行等,可能会乘以总空间。这在很大程度上取决于写入模式。
您可以通过删除不必要的索引来节省很多。
如果将enum
列移动到表的顶部,每行几个字节:较少的对齐填充,平均每行 1.5 个字节,总共大约 1 MB,几乎不值得。看:
归档时间: |
|
查看次数: |
1223 次 |
最近记录: |