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

标签 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 子句中引入非索引列的阈值是多少?]]

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

最佳答案

如果您在“col”上有一个索引,那么运行您的第一个查询将更新数百万行;如果有可用的索引,您的第二个查询可能只会更新一些并快速找到它们。如果您在该列上没有索引,则效果将是微不足道的,因为必须进行全表或索引扫描以检查表中的所有行(您只会有更少的实际更新,但仅此而已)。

使用 WHERE 子句限制查询的全部目的是缩小查询范围,例如SQL Server 必须查看的行数。处理更少的数据总是比只处理数百万行要快......

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

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

很明显,另一个标准或索引不再有帮助了。如果是这种情况,通常另一个 WHERE 子句不会有太大帮助 - 或者根本没有帮助。但是在这种情况下,SQL 查询优化器会找到这些情况并将它们过滤掉(甚至可能在决定最佳查询执行计划时忽略它们)。

关于sql - sql优化什么时候变得矫枉过正?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2074654/

相关文章:

sql-server - 检查 BCP .dat 文件的简单方法?

sql-server - 一个非常复杂的SQL查询问题

sql - 这是做什么的?

sql - 单词 join 处或附近的语法错误

mysql - MYSQL中如何拼接一个组中前N条记录的查询结果

python - pymssql utf8 : queries with back slash

sql-server - SQL Server - 用存储过程替换 View

sql - 如何使用SQL中的输出子句将插入、更新、删除结果输出到新的临时表中?

c# - ADO 异步查询超时

sql - bigquery 从日期中减去 3 个工作日