什么时候sql优化变得矫枉过正?

时间:2010-01-15 20:44:04

标签: sql sql-server tsql

我正在更新包含数百万条记录的表格,我需要尽可能高效。是否有一点可以在where子句中添加更多标准而不是帮助?

例如,如果知道我想将列设置为3,我可以使用此查询:

update mytable set col = 3

或者我只能在记录不同的情况下更新记录

update mytable set col = 3 where col <> 3

我也可以过滤它,因此它只更新自上次运行此过程以来添加的记录

update mytable set col = 3 where col <> 3 and createDate > @lastRunDate

也许我可以在其他专栏中寻找更多内容。

我想我的问题是,是否有一个点,其中查看额外列的成本超过更新本身的成本,如果有一个原则,您可以用来确定在哪里绘制线。

更新

所以这里的原则是我试图根据所说的拼凑起来。请随意与此争论,我会相应更新:

    <击>
  1. 如果没有要过滤的索引列,请添加尽可能多的条件以限制更新的记录,因为无论如何都会发生全表扫描。

  2. 如果仅对索引列进行过滤和对所有可能列进行过滤之间的记录差异很小,则只使用索引列并避免全表扫描。

  3. 如果您混合使用索引列和非索引列,请务必使用索引列,如果可以,则仅使用非索引列。 .. [[我还在努力解决这个问题。在where子句中引入非索引列的阈值是什么?]]

  4. 更新#2 听起来我有我的答案。

2 个答案:

答案 0 :(得分:6)

如果你有“col”的索引,那么运行你的第一个查询将更新数百万行,无论如何;如果有可用的索引,您的第二个查询可能只会更新一些并快速找到它们。如果您没有该列的索引,则效果将是边缘的,因为必须进行完整的表或索引扫描才能检查表中的所有行(您只需要更少的实际更新,但就是这样)。

限制查询usnig WHERE子句的重点是缩小查询范围,例如: SQL Server必须查看的行数。要处理的数据少于始终,而不是仅仅执行数百万行......

响应您的更新:使用WHERE子句的主要目标是减少需要检查/触摸的行数。如果你有一个手段(通常是一个指数)将这个数字从100%减少到几个百分点,那么它绝对值得。这就是拥有索引的重点(主要是针对SELECT,但当然也适用于其他操作)。

如果你有一个合适的索引,因此你可以拨出几百行来检查标准而不是检查数百万行,你总会更快。如果你在书店里有一本好的书籍索引,可以很容易地引导你到你感兴趣的书籍所在的两个书架上,你会发现你所需要的东西比你必须纵横交错整个书店的时间更快。因为没有可用的索引。

显然还有另一个标准或指数不再有用的地方。如果是这种情况,通常另一个WHERE子句实际上并没有多大帮助 - 或者根本没有。但在这种情况下,SQL查询优化器将找到这些情况并将其过滤掉(甚至可能在决定最佳查询执行计划时忽略它们)。

答案 1 :(得分:2)

这实际上归结为索引使用和查询优化。在做出任何决定之前,我建议查看查询计划。

将索引字段添加到where子句通常会缩短查询时间,但是,添加非索引字段会导致表扫描,这会降低查询速度。

我的建议是编写一个有效的查询,查看执行时间,通过查看查询计划将其降低到可以达到的水平。不要过度优化,寻求可接受的解决方案。