独特约束如何影响Postgres DB中的写入性能

时间:2012-11-02 06:55:01

标签: performance postgresql unique-constraint

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

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

1 个答案:

答案 0 :(得分:24)

创建UNIQUE约束或PRIMARY KEY会导致创建UNIQUE btree索引。如果任何索引列已更改INSERTUPDATEDELETE d,则必须更新此索引。如果没有更改索引列,则HOT(仅堆积元组优化)可以启动并避免索引更新,尤其是如果您有非默认FILLFACTOR以在页面中留出空间。

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

INSERT索引列上的每个UPDATEUNIQUE都需要进行索引查找,以验证密钥是否与现有密钥冲突。从模糊的记忆中,这与将新条目插入索引的过程相结合,但我并不是100%肯定。

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

即使您ROLLBACK事务或事务在UNIQUE受约束列上成功插入或更新后因错误而中止,索引也会更新。 autovacuum的VACUUM工作稍后会清除死索引条目。请参阅Concurrency Control in the PostgreSQL manual

PRIMARY KEY也是如此,这也是使用UNIQUE索引实现的。

每个索引(包括PRIMARY KEYUNIQUE约束使用的索引)都会对写入性能造成惩罚。