想象一下,我在 Postgres 13 中有一个像这样的表:
CREATE TABLE public.people (
id integer PRIMARY KEY,
full_name character varying(255),
bio text
);
Run Code Online (Sandbox Code Playgroud)
然后,我插入一行,其中包含足够的字符,以便将 Bio 写入 TOAST 表(4000 个随机字节,应压缩到 > 2Kb):
# insert into people values (1, 'joe toast', (SELECT array_to_string(ARRAY(SELECT chr((65 + round(random() * 25)) :: integer) FROM generate_series(1,4000)), '')));
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
然后插入一行,其中包含足够的字符用于 Bio Fit 内联(3000 个重复字节,应压缩至 < 2Kb):
# insert into people values (2, 'joe compressed', (SELECT array_to_string(ARRAY(SELECT chr(65) FROM generate_series(1,3000)), '')));
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
最后在简介中插入一行仅包含几个字符的行,以便它将存储内联(10 个重复字节):
# insert into people values …
Run Code Online (Sandbox Code Playgroud) 一个较旧的问题涵盖了为什么单个事务中多个 INSERTS 的性能随着 INSERT 计数的增长而非线性的一些原因。
按照那里的一些建议,我一直在尝试优化在单个事务中运行多个更新。在实际场景中,我们正在批处理来自另一个系统的数据,但我有一个较小的场景进行测试。
鉴于 postgresql 9.5.1 上的这个表:
\d+ foo
Table "public.foo"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+--------------------------------------------------+---------+--------------+-------------
id | bigint | not null default nextval('foo_id_seq'::regclass) | plain | |
count | integer | not null | plain | |
Run Code Online (Sandbox Code Playgroud)
我有以下的测试文件:100.sql
,1000.sql
,10000.sql
,50000.sql
和100000.sql
。每个包含以下行,UPDATE
根据文件名重复:
BEGIN;
UPDATE foo SET count=count+1 WHERE id=1;
...
UPDATE foo SET count=count+1 WHERE id=1;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
当我对加载每个文件进行基准测试时,结果如下所示: …
想象一下,我在 Postgres 13 中有一个像这样的表:
CREATE TABLE public.people (
id integer PRIMARY KEY,
full_name character varying(255),
bio text
);
Run Code Online (Sandbox Code Playgroud)
然后,我插入一行包含足够字符的行,以便将简介写入 TOAST 表:
# insert into people values (1, 'joe user', (SELECT array_to_string(ARRAY(SELECT chr((65 + round(random() * 25)) :: integer) FROM generate_series(1,4000)), '')));
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
最后,我更新该行而不更改 TOAST 列:
# update people set full_name='jane user' where id=1;
UPDATE 1
Run Code Online (Sandbox Code Playgroud)
是否UPDATE
更改关联 TOAST 表中的任何行(或根本需要任何写入)?
上下文:我正在处理一些每秒有数千个事务的数据库表,并且观察到服务器上的写入负载非常高。我想知道UPDATE
TOAST 中具有较大值但 TOAST 值本身大部分不变的元组是否会增加写入负载并且值得优化。