1

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

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

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

8 回答 8

4

一般来说,第二种情况(使用 WHERE)子句会更快——因为它不会在未使用的行上导致触发器评估、事务日志记录、索引更新等。

可能 - 根据 0/1 值的分布,更新所有行而不是进行比较实际上可能更快 - 但这是一个相当退化的情况。

由于约 95% 的查询成本是 I/O,使用 WHERE 子句要么没有区别(因为列没有索引,而你正在执行表扫描),要么有很大的不同(如果列被索引,或分区表等)。无论哪种方式,它都不会受到伤害。

我怀疑对于您所说的数据量,您不会注意到执行计划或速度的差异 - 这使得它充其量是学术性的,最坏的情况是过早优化。因此,我建议您选择对您的应用程序有意义的任何逻辑。

于 2008-09-23T23:28:49.223 回答
3

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

于 2008-09-23T22:30:23.903 回答
3

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

使用哪种方式并不重要,但最短的可能会出错。你不写的代码不能有错误。

于 2008-09-23T22:34:06.000 回答
2

这些转弯多久发生一次?您希望此表中有多少行?如果答案是“少于每秒一次”和“少于 10000”,请不要担心。

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

于 2008-09-23T22:54:03.973 回答
1

使“更新城市 SET usedBuilding = 0;”的交易数量似乎减少了。执行比更具体的查询。我能想到的反对这一点的主要原因是,如果您的专栏中有多个州。如果它只是一个布尔值,那么它会很好,但您可能需要花一些时间思考是否总是如此。

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

于 2008-09-23T22:31:33.370 回答
1

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

于 2008-09-23T22:34:02.990 回答
1

除非您拥有类似于 usedBuilding = 1 值的 2% 的东西,否则索引根本不会帮助您。

然而,这两个陈述在逻辑上是不同的,并且可能意味着完全不同的事情。但是,如果对于您的情况,它们是相同的,则使用没有 where 子句的那个。

于 2008-09-23T22:42:03.703 回答
1

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

如果您要对“城市”表进行多次更新,如果可能的话,最好在一个 UPDATE 语句中完成所有这些更新。

Making any change to a row probably takes just as much I/O as writing the entire row (except of course updating indexed columns also requires index writes), so you lose out by making several UPDATEs which hit lots of rows.

But if you have, say, <1000 rows, you really don't care :)

于 2008-09-24T05:31:27.043 回答