在SQL Server中,哪个查询执行得更好?

时间:2014-01-10 18:47:44

标签: sql sql-server performance

- 假设我想:

UPDATE Foo SET Bar = 1 WHERE ID = 187

- 或者我可以通过

完成同样的事情
UPDATE Foo SET Bar = 1 WHERE Bar <> 1 AND ID = 187

- 或者我可以通过

完成同样的事情
IF EXISTS (SELECT * FROM Foo WHERE Bar <> 1 AND ID = 187)
UPDATE Foo SET Bar = 1 WHERE ID = 187

假设上面的查询都是有效的并且具有相同的行为(我知道它们可能与某些触发器或其他数据库活动的行为不同),是否有性能原因选择一个?如果Bar在大部分时间已经运行了怎么办?

第二个查询似乎表现得更好并且写入次数更少,但我认为SQL足够智能来优化它。

第3个查询将进行2次搜索/扫描/等以找到该行,如果Bar&lt;&gt; 1,但在已经为1的情况下可能会更快。

3 个答案:

答案 0 :(得分:1)

答案总是很长,你需要在环境中测试一些变化,即使是简单的东西:)。

但您需要考虑的最大因素是索引。

如果您的表在该id字段上编入索引,那么与在其他一些不相关的列上建立索引相比,这将产生巨大的差异。 如果它在Bar而非Id上编入索引,那么搜索Bar&lt;&gt; 1可能会有帮助。

如果在两者(id,bar)上编入索引,则可能是此更新的最佳选择 这可能会使您选择的陈述真正无关紧要。

查看这篇高度投票的帖子中的链接:

How to read an execution plan in SQL Server

将目标系统中的一堆记录转储到目标系统中,并尝试不同的

组合
  • 索引
  • 和查询

看看你得到了什么。

答案 1 :(得分:0)

好吧,前两个查询不会产生相同的结果,除非所有行都有ID值= 187。

第一个查询会更新中的所有行,以使Bar = 1且ID = 187。 第二个查询将确保ID = 187的所有行都具有BAR值= 1

一般来说,最简单的SQL是一个很好的起点。

Update Foo SET BAR = 1 where ID = 187

在性能调整时,如果有很多行已经有BAR值= 1,那么你可以添加:

WHERE BAR <> 1 and ID=187 

避免无关更新,虽然引擎可能已经针对这种情况进行了优化,这就是为什么从最简单的选项开始然后分析/调优通常是最好的。

答案 2 :(得分:0)

我建议使用bar&lt;&gt; 1,因为它会更新id = 187的所有行,无论是否需要更新。为什么在只需要更新11时更新923,498行?添加where&lt;&gt;这是一个好习惯。条款。当然,它不会对小更新产生太大影响,但如果它是习惯,你就不会忘记什么时候你需要做一个大的更新。