【问题标题】:How does unique constraint affect write performance in Postgres DB唯一约束如何影响 Postgres DB 中的写入性能
【发布时间】:2012-10-22 20:14:46
【问题描述】:
在列或列组上指定的UNIQUE 约束是否会以任何方式影响 Postgres DB 的写入性能?它在内部是如何运作的?
我的意思是,它是否在插入新记录时执行唯一检查?如果是,它是如何做到的,它是否对数据库中已经存在的重复值进行线性搜索?在这种情况下,它被认为会影响性能,即唯一约束的数量越多,写入/插入性能就越差?这是真的吗?
【问题讨论】:
标签:
performance
postgresql
unique-constraint
【解决方案1】:
UNIQUE 约束或PRIMARY KEY 的创建会导致UNIQUE btree 索引的创建。每当任何记录为INSERTed、UPDATEed 或DELETEd(如果任何 索引列发生更改)时,都必须更新此索引。如果没有更改索引列,则 HOT(仅堆元组优化)可能会启动并避免索引更新,特别是如果您有非默认 FILLFACTOR 以在页面中腾出空间。
插入/更新时的索引更新需要时间,因此插入UNIQUE 索引表比插入没有任何唯一索引或主键的表要慢。 UPDATE 也是如此,但如果使用索引来查找要更新的元组(并避免 seqscan),则通常是净胜于根本没有索引。如果使用不同的索引来查找元组,或者如果 seqscan 更快(在小型表上也是如此),那么就像INSERT 一样,索引没有任何好处,只会产生写入成本来为该操作更新它。这适用于所有索引,而不仅仅是 UNIQUE 索引。
UNIQUE 索引列上的每个 INSERT 或 UPDATE 都需要进行索引查找,以验证该键与现有键不冲突。根据模糊的记忆,这与将新条目插入索引的过程相结合,但我不是 100% 确定那里。
AFAIK DELETE 不会影响索引。它只是为堆中的元组设置xmax。
即使您ROLLBACK 事务或事务在UNIQUE 约束列上成功插入或更新后因错误而中止,索引也会更新。 VACUUM autovacuum 的工作稍后会清理死索引条目。见Concurrency Control in the PostgreSQL manual。
PRIMARY KEY 也是如此,这也是使用 UNIQUE 索引实现的。
每个索引,包括PRIMARY KEY 和UNIQUE 约束使用的索引,都会导致写入性能下降。