2012-08-31 51 views
2

如果我想更新具有相同值的字段。为表中所有行更新一个具有相同常量的字段值...更好的表现方式?

例如,表笔,用severals列:A,B,C

是否更好地运行这样一句话:

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

这一个:

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

我第一个想到的可能会更快(即使我有基于B指数)?

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

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

+1

'EXPLAIN'显示每条语句的含义是什么? – Kermit

+0

@njk:嗡嗡声..我不知道..不是专家用mysql ...我看... – Whiler

+0

所有取决于你有多少'B = 0'。如果缓存大部分数据,更新数据库可能很昂贵。 – Grzegorz

回答

2

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

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

  • 对B无指数将执行全表扫描。

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

  • 具有高选择性,即几命中仍然会创建随机I/O,但只短短的必要 - 这是最好的情况。

所以根据需要更新的行的百分比,就应该全表扫描(=无WHERE),并有针对性的方法(= WHERE索引)

+0

谢谢对于不同的场景 – Whiler

1

恕我直言,第一个会更快...其中的值不是目标值

据我所知MySQL只自动更新列 - 所以是一个双重检查的“值”,它会遍历EVER在行上。 你的第二个方法是将迭代两次,如果没有这是完全没有好检查与where子句的索引。

+1

这正是我**认为的** ... – Whiler

1

除了性能,你应该知道之间的选择关于实际情况的差异。

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

当你并发交易你的发布选项是不一样的。第一个保证提交后的每一行是b=0。第二个仅保证提交后b<>0的每一行都设置为0。但是另一个交易可以将b=0的某行同时更改为另一个值。

所以即使你不关心不同的行为,你应该关心整个性能,当你有并发交易。这可能是第一个选项更快,但它阻止访问此表行的所有其他事务,而第二个选项并非如此。

+0

感谢这些细节 – Whiler

相关问题