6

我正在编写一个大脚本,里面充满了每天都会运行的更新语句。其中一些更新将影响其他行不会。

我相信不会影响任何事情的更新语句不是很好的做法,但我的问题是:

  • 这对性能有多大影响?这与仅在 select 获取某些内容时使用 select 语句和更新有很大不同吗?

谢谢你,蒂亚戈

4

3 回答 3

7

首先,SELECT 后跟 UPDATE 在并发下几乎总是不正确的。除非事情在 SERIALIZABLE 隔离级别下运行,否则无法保证SELECT 和 UPDATE之间的行不会更改。

其次,对于有要更新的行的情况 SELECT + UPDATE 的成本根据定义要高于 UPDATE。

最后,在没有行更新的情况下,通过 UPDATE 定位它们的成本通常与通过 SELECT 定位它们的成本相同,因此您没有获得任何收益。我说“经常”,而不是“总是”,因为查询优化器可能会考虑更新与选择的不同策略,并且更新扫描发生在与读取扫描不同的锁定(并发)规则下。

可能有意义的是有一个非常便宜的 SELECT 可以避免昂贵的 UPDATE,即使不是 100% 准确。SELECT 和 UPDATE 之间的条件可能会有很大差异只要你没有得到任何假阴性(SELECT 说不应该有任何行但 UP​​DATE 会找到行,如果它已经运行)和错误的数量正数很低(SELECT 表示有行,但更精确/更昂贵的 UPDATE 检查实际上并没有找到任何行)。

归根结底,这是一个优化问题,所有优化问题都是从测量开始的。先定位到昂贵的UPDATE,然后开始修改。

于 2012-05-31T13:26:31.873 回答
2
于 2012-05-31T13:08:12.480 回答
1

这取决于您如何进行更新。如果您使用连接语法进行更新(即)

UPDATE targetTable
FROM targetTable INNER JOIN sourceTable

然后,您可以非常简单地添加 WHERE 子句,仅当您要设置的值实际上不同时才更新该行。

是的,它会影响性能,特别是如果你认为这样的事情......

UPDATE targetTable SET column = column

...将触发在 UPDATE 上定义的触发器。我不是 100% 同意这一点,但我相信这也确实会进入事务日志,因为需要对其进行维护,以便日志尾备份和镜像目标能够完全拼凑事件序列。

于 2012-05-31T10:49:05.300 回答