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

ada*_*101 3 sql t-sql sql-server

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

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

update mytable set col = 3
Run Code Online (Sandbox Code Playgroud)

或者我只有在记录不同时才能更新记录

update mytable set col = 3 where col <> 3
Run Code Online (Sandbox Code Playgroud)

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

update mytable set col = 3 where col <> 3 and createDate > @lastRunDate
Run Code Online (Sandbox Code Playgroud)

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

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

更新

所以这就是我试图根据所说的内容拼凑起来的原则.随意与此争论,我会相应地更新它:

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

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

  3. 如果你有索引列和非索引列的混合,如果可以的话,肯定使用索引列,如果... [我仍然在努力使用这部分,那么只使用非索引列.在where子句中引入非索引列的阈值是什么?]]

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

mar*_*c_s 6

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

限制查询usnig WHERE子句的重点是减少查询范围,例如SQL Server必须查看的行数.处理数据的速度总是快于数百万行......

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

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

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

  • +1 - 更好地将更新限制为要更新的最小记录数,而不仅仅是对更多行进行全面更新.过度更新会导致更多写入. (2认同)