20

UNIQUE对一列或一组列指定的约束是否会以任何方式影响 Postgres DB 的写入性能?它在内部如何运作?

我的意思是,它是否在插入新记录时执行唯一检查?如果是,它是如何做到的,它是否对数据库中已经存在的重复值进行线性搜索?在这种情况下,它被认为会影响性能,即唯一约束的数量越多,写入/插入性能就越差?这是真的吗?

4

1 回答 1

40

UNIQUE约束或PRIMARY KEY结果的创建导致btreeUNIQUE索引的创建。INSERT每当任何记录被ed、UPDATEed 或DELETEd 如果任何索引列发生更改时,都必须更新此索引。如果没有更改索引列,则 HOT(仅堆元组优化)可能会启动并避免索引更新,特别是如果您有非默认设置FILLFACTOR以在页面中腾出空间。

插入/更新时的索引更新需要时间,因此插入UNIQUE索引表比插入没有任何唯一索引或主键的表要慢。也是如此UPDATE,但是如果使用索引来查找要更新的元组(并避免 seqscan),则通常是净胜于根本没有索引。如果使用不同的索引来查找元组,或者如果 seqscan 更快(在小型表上也是如此),那么就像INSERT索引没有任何好处,只会产生写入成本来为该操作更新它。这适用于所有索引,而不仅仅是UNIQUE索引。

每个INSERTUPDATEUNIQUE索引列上都需要索引查找来验证键与现有键不冲突。从模糊的记忆中,这与将新条目插入索引的过程相结合,但我不是 100% 确定那里。

AFAIKDELETE不影响索引。它只是xmax为堆中的元组设置。

即使事务或事务在成功插入或更新受约束的列ROLLBACK后因错误而中止,索引也会更新。autovacuum 的工作稍后会清理死索引条目。请参阅PostgreSQL 手册中的并发控制UNIQUEVACUUM

所有这一切对于 a 也是如此PRIMARY KEY,它也是使用UNIQUE索引来实现的。

每个索引,包括由PRIMARY KEYUNIQUE约束使用的索引,都会导致写入性能下降。

于 2012-11-02T07:12:54.463 回答