2

如果我想更新具有相同值的字段。

例如,一个表 T,有几个列:A、B、C

运行此语句是否更好:

UPDATE `T` SET `B` = '0';

或者这个:

UPDATE `T` SET `B` = '0' WHERE `B` <> '0';

我认为第一个可能会更快(即使我在 B 上有一个索引)?

如果我有数百万行..应用此更新会很长还是真的很快?

(我尝试搜索一个现有的类似问题......但我使用的关键字很难......太多不同的问题......不要犹豫,给我指出一个好问题......)

4

3 回答 3

2

相对性能取决于 的选择性WHERE B <> 0

  • 没有WHERE子句将执行全表扫描。

  • B 上的任何索引都不会执行全表扫描。

  • B 上具有低选择性的索引,即许多命中将产生高速率的随机 I/O,因为在索引中找到的行被寻址以进行更新。在大多数系统中,这将成为性能瓶颈。如果选择性非常低,您最终可能会得到全表扫描的很大一部分,但是是伪随机而不是顺序扫描——这是最坏的情况。这可能会在查询计划生成期间进行优化,并由全表扫描代替。

  • 高选择性,即很少的命中仍会创建随机 I/O,但只在必要时创建 - 这是最好的情况。

因此,根据需要更新的行的百分比,您应该在全表扫描 (= no WHERE) 和有针对性的方法 (= WHEREwith index)之间进行选择

于 2012-08-31T21:32:22.250 回答
1

恕我直言,第一个会更快...

afaik mysql 仅自动更新值不是目标值的列 - 因此对“值”进行双重检查,它将永远迭代行。在您的第二种方法中,它将迭代两次,如果没有索引,则使用 where 子句检查是完全不好的。

于 2012-08-31T21:21:03.960 回答
1

除了性能之外,您还应该了解交易上下文的差异。

第一个选项要求 MySQL 锁定所有行,第二个选项只需要锁定其中的行B <> '0'。使用 InnoDB,当有索引时,MySQL 能够做到这一点B

当您有并发交易时,您发布的选项不一样。第一个保证提交后的每一行都是b=0. 第二个只保证每行在b<>0提交后都设置为 0。但是另一个事务可以同时将某些行更改b=0为另一个值。

因此,即使您不关心不同的行为,您也应该关心并发事务时的整体性能。可能是第一个选项更快,但它阻止了访问此表行的所有其他事务,而第二个选项不是这种情况。

于 2012-09-02T11:24:01.550 回答