我正在编写一个大型脚本,其中包含每日运行的更新语句。其中一些更新会影响其他人不会的行。
我认为不会影响任何事情的更新语句不是很好的做法,但我的问题是:
谢谢你, 蒂亚戈
答案 0 :(得分:4)
首先,在并发下,SELECT后跟UPDATE几乎总是不正确的。除非事情在SERIALIZABLE隔离级别下运行,否则无法保证行不会在 SELECT和UPDATE之间更改。
其次,对于要更新 行的情况,SELECT + UPDATE的成本定义高于UPDATE。
最后,对于不是行来更新UPDATE定位它们的成本的情况通常与SELECT定位它们的成本相同,所以你没有获得任何东西。我说'经常',而不是'总是',因为查询优化器可能会考虑更新与选择的不同策略,并且扫描更新发生在不同的锁定(并发)规则下,而不是扫描读取。
可能有意义的是拥有一个非常便宜的SELECT,可以避免昂贵的更新,即使不是100%准确。 SELECT和UPDATE之间的条件可能会有很大差异只要你没有得到任何漏报(SELECT说不应该有任何行,但UPDATE会找到行,如果已经运行了)和false的数量积极性很低(SELECT表示有行,但更精确/更昂贵的UPDATE检查实际上找不到任何行。)
最终这是一个优化问题,所有优化问题都以测量开始。首先找到昂贵的UPDATE ,然后开始修改。
答案 1 :(得分:2)
如果您想询问UPDATE … WHERE condition
和SELECT … WHERE the_same_condition
+ UPDATE … WHERE the_same_condition
在效果方面是否存在差异,那么我宁愿期望后者更少比前者高效。无论是UPDATE
还是SELECT
,行仍然需要计算出来,而对于初步SELECT … WHERE …
,如果有点击,则必须计算两次。
但@Matt Whitfield has got a point关于触发器。如果在更新时触发,则无论是否更新任何行,都会触发。如果触发器有的东西,即使没有更新行(并且你想避免这种情况),那么要么重写你的触发器,要么继续使用SELECT
+ { {1}}方法。
答案 2 :(得分:1)
这取决于您是如何进行更新的。如果您使用加入的语法(即。)
进行更新UPDATE targetTable
FROM targetTable INNER JOIN sourceTable
然后你可以简单地添加WHERE子句,只有在你想要设置的值实际上不同时才更新行。
是的,它会影响性能,特别是如果你考虑这样的事情......
UPDATE targetTable SET column = column
...将触发在UPDATE上定义的触发器。我不是百分之百,但我相信这也会进入事务日志,因为需要维护它以便日志尾部备份和镜像目标能够完全拼凑事件序列。 / p>