在mysql中更新行时,在有或没有附加条件的情况下,哪个语句更有效

在mysql中更新行时,在有或没有附加条件的情况下,哪个语句更有效,mysql,sql-update,Mysql,Sql Update,我正在使用mysql数据库,现在我必须确保列中的值应该是1,而它可能已经是1。因此,考虑到以下两种说法: UPDATE category SET is_leaf=1 WHERE id=9 或 id是主键,区别在于当is\u leaf已经为1时,是否更新它,哪个更有效 我知道这没什么大不了的,但我想了解一下,以便更好地理解mysql UPDATE category SET is_leaf=1 WHERE id=9 AND is_leaf=0 它的效率更高。因为它只更新相关数据。否则,即使为_l

我正在使用mysql数据库,现在我必须确保列中的值应该是
1
,而它可能已经是
1
。因此,考虑到以下两种说法:

UPDATE category SET is_leaf=1 WHERE id=9

id
是主键,区别在于当is\u leaf已经为1时,是否更新它,哪个更有效

我知道这没什么大不了的,但我想了解一下,以便更好地理解mysql

UPDATE category SET is_leaf=1 WHERE id=9 AND is_leaf=0
它的效率更高。因为它只更新相关数据。否则,即使
为_leaf=1
记录也将更新

假设表上有1000条记录,更新一条记录需要1s。如果您尝试更新所有记录,则需要1000秒。但是,假设在此场景中有
is_leaf=0
记录计数为150,则如果使用第二条语句,则只需要150秒,而不是1000秒

编辑:

带有搜索参数的查询(SARG)

WHERE子句帮助您限制查询返回的行数。但是,指定WHERE条件的方式可能会影响查询的性能。如果写入WHERE条件使其使用以索引列作为输入的函数,则忽略索引并扫描整个表。这会导致性能下降。 例如,由于函数中使用了OrderDate列,因此以下结果会导致表扫描:

SELECT CustomerID, EmployeeID FROM Orders
WHERE DATEDIFF(m, OrderDate, GetDate())>3
如果按如下所示重写函数,则查询将使用索引查找所需的值,这将提高性能:

SELECT CustomerID, EmployeeID FROM Orders
WHERE OrderDate < DATEADD(m, -3, GetDate())
从订单中选择CustomerID、EmployeeID
其中OrderDate
第二个查询中的筛选条件被称为使用可搜索参数或SARG,因为查询优化器可以在执行期间使用索引查找操作

有关这方面的更多信息,请阅读


也请阅读这篇文章

包含
和is_leaf=0的查询有时会更有效

在基于主键定位行时,这不会有多大区别。(在(id,is_leaf)
上的索引
的可用性可能会有一点不同。)但一旦MySQL发现没有要更新的行,它就可以使用更短的代码路径

但是,如果没有该谓词,MySQL将不得不定位该行,获得一个行锁(在InnoDB的情况下),并触发任何“每行更新前”触发器。然后MySQL必须检查是否有任何列值实际被更改(请注意,触发器的执行可能会将一个或多个列设置为不同的值)。如果MySQL检测到行没有变化,它可以跳过任何“更新时”时间戳列的设置,触发任何“每行更新后”触发器,并将受影响的行数设置为零。(在事务上下文中,不清楚MySQL在确定行未被更改后是否可以释放行锁,或者在提交或回滚之前是否会继续保留行锁。)

因此,这两个语句之间的一个大区别是,即使行没有实际更改,MySQL也会触发“FOR EACH ROW”触发器;但它不会为WHERE子句排除的行触发任何“FOR EACH ROW”触发器

在简单的情况下,如果没有任何触发因素,我不希望在性能上有任何可测量的差异

我个人的偏好是包含额外的谓词。这确保不会请求或保持(InnoDB)意图行锁,并且不会触发“FOR EACH row”触发器


除了行锁定和触发器执行之外,只要这两条语句完全相同,它们就不是真的。至少在一般情况下不是这样,在这种情况下,
is\u leaf
可能包含NULL或0或1以外的值

鉴于这一说法:

UPDATE category SET is_leaf=1 WHERE id=9
UPDATE category SET is_leaf=1 WHERE id=9 AND is_leaf=0
对于将
is_leaf
设置为1的等价语句,只要它还不等于1,我们实际上需要检查NULL和任何不同于1的值,例如:

UPDATE category SET is_leaf=1 WHERE id=9 AND NOT (is_leaf <=> 1)

有没有实验证据支持这一点?因为附加条件需要更多的时间来检查,例如,检查其值是否为0,然后更新它,或者只是在不检查的情况下更新它,问题是检查或更新哪个成本更高?当我们将值设置为
1
时,它已经是
1
,然后mysql会1)检查是否会实际更改,然后决定是否更新;或者2)无论如何都要更新它,然后监视它是否已更改?如果是第一种情况,那么我认为这两条语句做的事情完全相同(除了第二条语句需要更少的行锁)。
UPDATE category SET is_leaf=1 WHERE id=9 AND is_leaf=0