盲目更新或更新位置?

时间:2008-09-23 22:27:29

标签: mysql optimization sql-update

我有一个表格,其中包含游戏中有关城市的信息,您可以在每个回合中构建一个建筑物,并使用值“usedBuilding”进行记录。

每回合我都会运行一个脚本,将usedBuilding改为0,问题是,以下两种方式中的哪一种更快,实际上它使用哪种方式很重要?

UPDATE cities SET usedBuilding = 0;
UPDATE cities SET usedBuilding = 0 WHERE usedBuilding = 1;

8 个答案:

答案 0 :(得分:4)

通常,第二种情况(使用WHERE)子句会更快 - 因为它不会对未使用的行造成触发器评估,事务日志记录,索引更新等。

可能 - 取决于0/1值的分布,更新所有行实际上可能更快而不是进行比较 - 但这是一个非常简并的情况。

由于~95%的查询成本是I / O,因此使用WHERE子句将没有任何区别(因为列没有编入索引,并且您正在进行表扫描)或存在巨大差异(如果列被索引,或表分区,等等。无论哪种方式,都没有伤害。

我怀疑,对于您正在谈论的数据量,您不会注意到执行计划或速度的差异 - 这使得它在学术上处于最佳状态,最糟糕的是过早优化。因此,我建议您使用逻辑上适合您应用的任何内容。

答案 1 :(得分:3)

如果usedBuilding已编入索引,则使用where子句会更快,因为它只会访问/更新usedBuilding为true的行。 如果它没有编入索引,那么你无论如何都会进行全表扫描,因此不会产生太多(任何?)差异。

答案 2 :(得分:3)

在循环中尝试两种方式几千次并计时! 它可能取决于:此表中实际有多少条记录,以及它们是否都适合内存或必须分页到磁盘。在运行更新之前,有多少建筑物的值为1(我猜这可能是1)。

使用哪种方式无关紧要,但最短的方式可能最少可能出错。你不写的代码不能有bug。

答案 3 :(得分:2)

这些转变多久发生一次?您希望在此表中有多少行?如果答案是“少于一秒”和“少于10000”,那就别担心了。

当然,除非你恰好对此有某种学术兴趣。

答案 4 :(得分:1)

似乎会有较少数量的交易来使“UPDATE CITY SET usedBuilding = 0;”执行比更具体的查询。我可以想到的主要原因是你的专栏中有多个州。如果它只是一个布尔值那么它会没问题,但你可能想花一些时间思考是否总会如此。

索引还可以使用WHERE子句使执行计划更有效。

答案 5 :(得分:1)

获得明确答案的最佳方法是在不同情况下使用大量样本数据进行分析。

答案 6 :(得分:1)

索引根本不会帮助你,除非你有2%的usedBuilding = 1值。

然而,这两个陈述在逻辑上是不同的,可能意味着完全不同的事情。 但是,如果你的情况相同,那么使用没有where子句的那个。

答案 7 :(得分:1)

你到底有多少行?我怀疑对于一个小型的网络游戏,你真的不在乎。

如果您正在对“cities”表进行多次更新,如果可能的话,最好在一个UPDATE语句中执行这些更新。

对行进行任何更改可能需要与写入整行一样多的I / O(当然,更新索引列也需要索引写入除外),因此您可以通过创建多个UPDATE来输掉许多行。 / p>

但是如果你有,比方说,< 1000行,你真的不在乎:)