3

是的,fillfactor再次。我花了很多时间阅读,我无法决定每种情况下什么是最好的。我不明白碎片何时以及如何发生。我正在将数据库从 MS SQL Server 迁移到 PostgreSQL 9.2。

情况1

在顺序(串行)PK 中 10-50 次插入/分钟,20-50 次读取/小时。

CREATE TABLE dev_transactions (
  transaction_id serial NOT NULL,
  transaction_type smallint NOT NULL,
  moment timestamp without time zone NOT NULL,
  gateway integer NOT NULL,
  device integer NOT NULL,
  controler smallint NOT NULL,
  token integer,
  et_mode character(1),
  status smallint NOT NULL,
  CONSTRAINT pk_dev_transactions PRIMARY KEY (transaction_id)
);

案例2

类似的结构,串行PK的索引,每2个月写入约50.000个寄存器的块(一次),读数10-50 /分钟。

50% 的填充因子是否意味着每次插入都会生成一个新页面并将 50% 的现有行移动到新生成的页面?

50% 的填充因子是否意味着在新数据页的物理行之间分配了释放空间?

仅当现有页面中没有可用空间时才会生成新页面?

如您所见,我很困惑;我会很感激一些帮助——也许是阅读 PostgreSQL 和 index 的好链接fillfactor

4

1 回答 1

13

FILLFACTOR

with onlyINSERT并且SELECT你应该在任何地方使用FILLFACTORof 100。如果您不打算与UPDATEs 一起“摆动”,那么为每个内存块留出摆动空间是没有意义的。

背后的机制FILLFACTOR很简单。INSERTs 仅将数据页(通常为 8 kB 块)填充到FILLFACTOR设置声明的百分比。此外,无论您何时奔跑VACUUM FULLCLUSTER在桌面上,都会重新建立每个街区的相同摆动空间。理想情况下,这允许UPDATE在同一数据页中存储新的行版本,这可以在处理大量UPDATEs 时提供显着的性能提升。与HOT 更新结合使用也有好处。看:

如果没有更新,不要为此浪费空间并设置FILLFACTOR = 100(这是表的默认设置)。

CREATE TABLE基本信息来源:和的手册CREATE INDEX

其他优化

但是您可以做其他事情-因为您似乎是优化的傻瓜... :)

CREATE TABLE dev_transactions(
  transaction_id serial PRIMARY KEY
, gateway integer NOT NULL
, moment timestamp NOT NULL
, transaction_type smallint NOT NULL
, status smallint NOT NULL
, device integer NOT NULL
, controler smallint NOT NULL
, token integer
, et_mode character(1)
);

这优化了您的表格在数据对齐方面并避免了典型 64 位服务器的填充并节省了几个字节,平均可能只有 8 个字节 - 您通常不能使用“列俄罗斯方块:

将列保留NOT NULL在表的开头以获得非常小的性能奖励。

您的表有9 列。这意味着扩展的NULL 位图需要额外的8 个字节- 这将适合仅8 列的初始 1 字节 NULL 位图。 如果定义and ,则所有列都是并且永远不会使用 NULL 位图,每行释放 8 个字节。 如果您不声明columns ,这甚至适用于每行。如果所有列都有值,则该行没有 NULL 位图。在您的特殊情况下,这会导致悖论效应,即填充值并可以使您的存储大小更小或至少保持不变:
et_modetoken NOT NULLNOT NULL
NOT NULLet_modetoken

基本信息来源:数据库物理存储手册。

将行的大小(填充值)与原始表进行比较以获得明确的证据:

SELECT pg_column_size(t) FROM dev_transactions t;

(加上可能在行之间填充,因为下一行从 8 个字节的倍数开始。)

于 2013-01-06T22:14:59.740 回答