我有一个与绩效相关的问题.假设我有一个名叫迈克尔的用户.采取以下查询:
UPDATE users SET first_name = 'Michael' WHERE users.id = 123
查询是否会实际执行更新,即使它正在更新为相同的值?如果是这样,我该如何防止它发生?
由于Postgres的
MVCC model,并且根据sql的规则,UPDATE为WHERE子句中未排除的每一行写入新的行版本.
这确实对性能产生了或多或少的直接或间接影响. “空更新”与每个任何其他更新具有相同的每行成本.它们像任何其他更新一样触发触发器(如果存在),它们必须是WAL-logged并且它们会产生死行,使得表格膨胀,并且像其他任何更新一样导致VACUUM的更多工作.
索引条目和TOASTed列(其中没有更改任何列)可以保持不变,但对于任何更新的行都是如此.有关:
> PostgreSQL Initial Database Size
> Redundant data in update statements
排除这样的空更新几乎总是一个好主意(当有可能发生这种情况时).你没有在你的问题中提供表格定义(这总是一个好主意).我们必须假设first_name可以为NULL(这对于“名字”来说并不奇怪),因此查询必须使用NULL-safe comparison:
UPDATE users SET first_name = 'Michael' WHERE id = 123 AND first_name IS DISTINCT FROM 'Michael';
如果在更新之前first_name为NULL,则仅使用first_name<>进行测试’Michael’将评估为NULL,因此从更新中排除该行.偷偷摸摸的错误.如果该列是defined NOT NULL
,则使用简单的相等性检查,因为这样便宜一点.
有关:
> How do I (or can I) SELECT DISTINCT on multiple columns?
> SQL Update column with data from another table