我想编写一个语句,例如将is_new
更新为0,条件为mail.user_id=$user.id
等。
update mails set `is_new=0` WHERE `mails.user_id=$user.id`
我应该添加另一个条件来防止更新已经is_new
等于零的记录吗?像这样
update mails set is_new=0 WHERE mails.user_id=$user.id and is_new!=0
哪个声明最好?你觉得它还需要第二个条件吗?
答案 0 :(得分:1)
作为一个非常一般的原则,我将我的UPDATE查询结构化为" touch"实际需要触摸的记录。在我看来,出于性能原因这一点较少,出于可读性原因更多:后一种形式的查询更准确地说明了您尝试做的事情 - 即,您只想为那些记录设置is_new=0
其中is_new
还不是0.所以仅仅因为这个原因,我说应该有额外的条件。
更一般地说,有一个着名的计算机科学引用,"过早优化是所有邪恶的根源"。在使用MySQL查询时,我并不总是同意这个引用,但它提出了一个重要的观点:如果您对是否优化某些内容感到困惑,那么您实际上并没有尝试了两种格式和/或进行了测量,以确定优化产生了多大的差异,让您浪费时间。如果您在不知道它会产生什么差异的情况下进行优化,你确定的唯一结果就是你使你的工作变得更加复杂。
因此,不要出于性能原因进行优化,直到您知道(或有充分理由相信)优化会产生影响。但始终为了可读性和标准化原因而优化,因为您 知道人们将来必须阅读您的代码。至少这是我的规则。
答案 1 :(得分:1)
问题在于,当您在更新中设置值时,它实际上会覆盖旧值,这比检查是否应该覆盖该值需要更长的时间。所以,你有以下几种情况:
案例1:update
每is_new
到0
user_id
is_new
匹配且0
不是0
,则会正确更新为user_id
is_new
匹配并且0
已经update
,那么它会0
到set
,但这需要更长的时间,因为它是写操作案例2:is_new
0
至0
,如果尚未user_id
is_new
匹配并且0
不是0
,那么它会检查它是0
并因此正确地将其更新为user_id
is_new
匹配并且0
已经0
,那么它将检查它是否为update
并将保留记录假设您必须有x
x
条记录,但是,y
条记录中只有0
有is_new
is_new 。检查0
a
is_new
是否花费0
时间并将b
更新为is_new
需要0
次平均记录。在这种情况下:
如果您没有过滤掉update
已经x * b
的记录,那么:
您将is_new
所有记录,这需要0
时间。
如果您过滤掉is_new
已经x * a
的记录,那么:
您将检查y
以获取记录,这需要y * b
,然后您将更新x * a + y * b < x * b
记录,这需要SELECT
s.*
FROM
student AS s
INNER JOIN student_room AS sr ON s.roll_no = sr.roll_no
WHERE
sr.room_no NOT IN (6, 7)
;
。
直觉上,我认为写作花了很多时间,那就是:
LEFT JOIN
然而,肯定的是对它进行基准测试并查看一些测量结果,因为地球上没有人会告诉你你的mysql如何执行你的查询。
编辑:
基于评论,显然,文档指出如果字段更新为其当前值,那么MySQL将注意到该问题并且不会执行更新。
如果将列设置为当前的值,MySQL会注意到这一点 并且不会更新它。
这并没有改变这样一个事实:如果需要进行优化,就应该进行实验,因为如果证明引用错误,那么文档就不是第一次存在缺陷。此外,这些想法对其他情况也应该有用,因为引用只接触带有=运算符的条件,如果应该检查其他条件,引用的MySQL功能将不适用。
答案 2 :(得分:1)
根据我的经验和我的观点,答案很清楚 - 不要添加is_new != 0
。有几个原因,我会尝试列出它们:
SQL是关于解释您想要做什么的。添加条件也将告诉如何执行此操作。 MySQL已经过优化,足以避免工作超出预期。
添加条件不会使您的查询更具可读性。删除它。它明确指出您要将is_new
更新为基于user_id
的值
添加条件会导致潜在损害性能。注意 potential 这个词 - 我不是说它会,但它可能会。如果你无法优化某些东西是如何工作的,为什么你可能会让它变慢?只是不要。在你的情况下,我们可能正在谈论糟糕的表现值,但仍然。
添加条件将使MySQL做得更多。不多,但仍然 - 它会做更多。你真的不需要它。
MySQL在写入任何新内容之前检查该行是否确实已更改。如果is_new
为0
并且您想再次将其设置为0
- MySQL会注意到它并且它将跳过更新该行(写入操作比检查操作昂贵得多,所以MySQL将执行该检查。
手动引用:
如果将列设置为当前的值,MySQL会注意到这一点 并且不会更新它。
相关的源代码,如果需要:here