我很难找到关于如何在 PostgreSQL 中缓存索引的“外行”解释,所以我想对这些假设中的任何一个或所有假设进行现实检查:
buffer cache
与行位于相同的缓存(?)中,因此索引使用的缓存空间不可用于行。在开始之前,我想明确一点,使用部分索引会产生两个优势:
我有一个大约有一百万行的表。
它正在生产中使用,我运行了一个UPDATE
覆盖了大约 95% 的行。
之后5小时我取消了请求,因为它正在采取这么长时间。
该表有一个自动递增的 ID 列,因此我尝试将WHERE
查询条件扩展为包含id BETWEEN 1 AND 500
.
此更新在大约两秒钟内完成。然后我手动迭代了id
500 个批次,例如BETWEEN 500 AND 1000
, then BETWEEN 1000 AND 1500
。
按照这个速度,更新整个表需要 2000 个批次,每批次 500 个。
每 2 秒更新 2000 个批次只需一个多小时。
我的问题是:
运行时:
TRUNCATE TABLE YYYYY RESTART IDENTITY
Run Code Online (Sandbox Code Playgroud)
我看到此错误消息:
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "XXXXX" references "YYYYY".
HINT: Truncate table "XXXXX" at the same time, or use TRUNCATE ... CASCADE.
Run Code Online (Sandbox Code Playgroud)
中的两个建议HINT
:
使用TRUNCATE ... CASCADE
是有意义的,并且有效,但不太明确,因为必须检查YYYYY
以查看级联的去向。这让我想尝试另一种选择:
Truncate table "XXXXX" at the same time
,但我的问题是:
截断表是什么意思at the same time
?
我尝试添加 a TRUNCATE XXXXX...
(并将它们都包装在BEGIN
/ 中COMMIT
),但这会产生相同的错误。
我们在 PostgreSQL 数据库中有一个表,它每天以数百万行的速度增长。
每行包括:
ID
Foreign user ID
Date and time
Other data
Run Code Online (Sandbox Code Playgroud)
日期和时间不是严格单调的ID
,但它们很接近。
查询此表时,我们只对获取给定外部用户 ID 的行感兴趣,其中包含最近两周的日期和时间。永远不会查询超过两周的行,但我们希望保留它们以供存档。
鉴于此特殊用例:
我有一个表t
,其中有一列名为json
,类型为JSON
。在 JSON 中有一个自然键:
> SELECT json->'id' AS id FROM t LIMIT 1;
id
-----------------------------
" 63631ff3809de7a17398602f"
Run Code Online (Sandbox Code Playgroud)
我可以创建一个UNIQUE INDEX
on id
,因此:
> CREATE UNIQUE INDEX t_id ON t((json->>'id'));
CREATE INDEX
Run Code Online (Sandbox Code Playgroud)
我想将其添加为table_constraint_using_index,但两者都失败了PRIMARY KEY
:
> ALTER TABLE t ADD CONSTRAINT t_pkey PRIMARY KEY USING INDEX t_id;
ERROR: index "t_id" contains expressions
LINE 1: ALTER TABLE t ADD CONSTRAINT t_pkey
^
DETAIL: Cannot create a primary key or unique constraint …
Run Code Online (Sandbox Code Playgroud) postgresql ×4
performance ×3
cache ×1
cascade ×1
constraint ×1
index-tuning ×1
json ×1
truncate ×1
update ×1