FILLFACTOR
仅与INSERT
and SELECT
你应该使用FILLFACTOR
of 100
for tables(无论如何这是默认的)。如果您不打算“摆动”,则为每个数据页留出摆动空间是没有意义的UPDATE
s.
背后的机制FILLFACTOR
很简单。INSERT
仅填充数据页(通常是 8 kB 块),最多达到声明的百分比FILLFACTOR
环境。另外,每当你跑步时VACUUM FULL
or CLUSTER
在桌子上,每个块都重新建立了相同的回旋空间。理想情况下,这允许UPDATE
在同一数据页中存储新的行版本,这可以在处理大量数据时提供显着的性能提升UPDATE
s。结合使用也有好处热的。更新. See:
Indexes设计上需要更多的回旋余地。他们必须将新条目存储在叶页中的正确位置。一旦页面满了,就需要进行成本相对较高的“页面拆分”。因此索引往往比表更膨胀。默认FILLFACTOR
对于(默认)B-Tree 索引是90
(因索引类型而异)。回旋空间对于插入也有意义。最好的策略在很大程度上取决于写入模式。
示例:如果新刀片的价值稳定增长(典型情况serial
or timestamp
列),那么基本上没有分页,你可能会选择FILLFACTOR = 100
(或者稍微低一点以允许some noise).
对于新值的随机分布,您可能会低于默认的 90 ...
基本信息来源:手册CREATE TABLE and CREATE INDEX.
其他优化
但你可以做别的东西- 因为你似乎很喜欢优化......:)
CREATE TABLE dev_transactions(
transaction_id serial PRIMARY KEY
, gateway integer NOT NULL
, moment timestamp NOT NULL
, device integer NOT NULL
, transaction_type smallint NOT NULL
, status smallint NOT NULL
, controller smallint NOT NULL
, token integer
, et_mode character(1)
);
这可以优化您的表格数据对齐并避免padding对于典型的 64 位服务器来说,可以节省一些字节,平均可能只有 8 个字节 - 通常你不能用“列俄罗斯方块”挤出太多:
Keep NOT NULL
表开头的列可以获得非常小的性能奖励。
你的桌子有9 列。初始(“无成本”)1 字节 NULL 位图覆盖8 列。第 9 列触发额外的8 bytes对于延长的空位图- 行中是否有任何 NULL 值。
如果你做et_mode
and token
NOT NULL
,所有列都是NOT NULL
并且没有 NULL 位图,每行释放 8 个字节。
如果某些列可以为 NULL,这甚至对每行都有效。如果同一行的所有字段都有值,则该行没有 NULL 位图。在您的特殊情况下,这会导致填写值的悖论et_mode
and token
可以让你的存储大小smaller或者至少保持不变:
- 可为 null 的列会占用 PostgreSQL 中的额外空间吗?
基本信息来源:手册数据库物理存储.
将行的大小(填充值)与原始表进行比较以获得明确的证据:
SELECT pg_column_size(t) FROM dev_transactions t;
(另外,行之间可能会有填充,因为下一行以 8 字节的倍数开始。)