列或列组上指定的UNIQUE
约束是否会以任何方式影响Postgres DB的写入性能?它内部如何运作?
我的意思是,它是否在插入新记录时执行唯一检查?如果是,它是如何做到的,它是否对数据库中已存在的重复值进行线性搜索?在这种情况下,它被认为会影响性能,即更多的独特约束更糟糕的是写入/插入性能?这是真的吗?
答案 0 :(得分:24)
创建UNIQUE
约束或PRIMARY KEY
会导致创建UNIQUE
btree索引。如果任何索引列已更改INSERT
,UPDATE
或DELETE
d,则必须更新此索引。如果没有更改索引列,则HOT(仅堆积元组优化)可以启动并避免索引更新,尤其是如果您有非默认FILLFACTOR
以在页面中留出空间。
插入/更新的索引更新需要时间,因此插入UNIQUE
索引表比插入没有任何唯一索引或主键的表慢。 UPDATE
也是如此,但是如果索引用于查找要更新的元组(并避免使用seqscan),那么它通常是净赢,而根本没有索引。如果使用不同的索引来查找元组,或者如果seqscan更快(在小表上也是如此)那么就像INSERT
一样,索引没有任何好处,只需要花费写入成本来更新它操作。这适用于所有索引,而不仅仅是UNIQUE
索引。
INSERT
索引列上的每个UPDATE
或UNIQUE
都需要进行索引查找,以验证密钥是否与现有密钥冲突。从模糊的记忆中,这与将新条目插入索引的过程相结合,但我并不是100%肯定。
AFAIK DELETE
不会影响索引。它只是为堆中的元组设置xmax
。
即使您ROLLBACK
事务或事务在UNIQUE
受约束列上成功插入或更新后因错误而中止,索引也会更新。 autovacuum的VACUUM
工作稍后会清除死索引条目。请参阅Concurrency Control in the PostgreSQL manual。
PRIMARY KEY
也是如此,这也是使用UNIQUE
索引实现的。
每个索引(包括PRIMARY KEY
和UNIQUE
约束使用的索引)都会对写入性能造成惩罚。