2015-04-30 42 views
2

我想要写一个声明例如is_new与像mail.user_id=$user.idmysql中有一个优化和良好的更新语句吗?

update mails set `is_new=0` WHERE `mails.user_id=$user.id` 

的条件更新为0,我应该增加对防止更新已经有is_new等于零记录另一个条件?像这样

update mails set is_new=0 WHERE mails.user_id=$user.id and is_new!=0 

哪种说法是最好的?你是否认为还需要第二个条件?

+1

是ofcourse,您的第二个条件将减少执行时间 –

+1

您可能需要更新的NULL了。然后:'和is_new <> 0或is_new为空)'。 –

+0

MySQL文档陈述了这一点:'如果你将列设置为当前的值,MySQL会注意到这一点并且不会更新它。所以,你不需要第二个条件。只是保持简单。 –

回答

1

作为一个非常普遍的原则,我将我的UPDATE查询组织为只“触摸”实际需要触摸的记录。在我看来,由于性能方面的原因,出于可读性的原因更少:查询的后一种形式更准确地说明了您要做的事情 - 即,您只想为is_new尚未为0的记录设置is_new=0因此,仅仅因为这个原因,我会说额外的条件应该存在。

在一个更为一般的说明中,有一个着名的计算机科学报价“过早优化是万恶之源”。在处理MySQL查询时,我并不总是同意这个引用,但它提出了一个重要的观点:如果你对是否优化某些东西感兴趣,而且你没有真正尝试过这两种格式和/或通过测量来确定优化所产生的差异,这会浪费您的时间。如果您在不知道它会产生什么差异的情况下进行优化,您确定的唯一结果就是您将工作变得更加复杂。

所以,不要为了性能的原因进行优化,直到你知道(或有充分的理由相信)优化会有所作为。但总是优化的可读性和标准化的原因,因为你知道人们将不得不阅读你的代码在未来。至少这是我的规则。

+0

添加条件没有提高性能的机会。即使列被索引。添加条件来检查“is_new!= 0”实际上可以提高查询速度的速度。 –

+1

取决于发出写入的实际速度,检查条件的实际速度,要更新的元素数量以及is_new不是0的子集。取代机会和意见,基准测试将有最后的决定权 –

+0

谢谢为额外的信息家伙。我想我上面的观点是,除非你有充分的理由认为速度会成为问题,否则不值得优化速度;但它*值得构造你的查询,尽可能的清楚它所做的事情,即使这意味着增加一个额外的WHERE条件(除非这会导致一些可怕的性能问题,在这种情况下可以参见上文)。 –

1

问题是,当您在更新中设置值时,它实际上会覆盖旧值,这比检查值是否应该被覆盖花费更长的时间。所以,你有以下情况:

案例1:您updateis_new0

  • 如果user_id比赛和is_new0,那么它将正确地进行更新,以0
  • 如果user_id比赛和is_new已经是0,那么它将update0,但它会花费更长的时间,因为它是一个写操作

案例2:你setis_new0,如果它是不是已经0

  • 如果user_id比赛和is_new0,那么它会检查它是否是0,因此,正确地更新它0
  • 如果user_id匹配和is_new已经0,那么它会检查它是否是0并且将le AVE记录,因为它是

让我们假设你有updatex记录,但是,从x记录,只有y有没有0 is_new。检查is_new是否0需要a时间并更新is_new0需要b时间才能平均记录。在这种情况下:

如果不筛选出记录,其中is_new已经0,则: 你会update所有的记录,这需要时间x * b

如果您筛选出记录,其中is_new已经0,则: 您将检查is_new的记录,这需要x * a然后将更新y记录,这需要y * b

直观地说,我认为写作花费如此多的时间,即:

x * a + y * b < x * b 

但是,肯定的事情将是标杆,看看一些测量,因为地球上没有人会告诉你如何你的mysql在引擎盖下执行你的查询。

编辑:

根据意见,显然,该文件指出,如果一个字段更新为当前值,那么MySQL会注意到这个问题,并不会执行更新。

如果您将列设置为当前的值,MySQL会通知此 并且不会更新它。

Source

这并不改变这样一个事实,即如果需要进行优化,应该进行实验,因为如果报价被证明是错误的,那么这不会是文档首次出现缺陷。此外,这些想法对其他情况也应该是有用的,因为引用仅涉及=运算符的条件,并且如果应该检查其他条件,引用的MySQL功能将不适用。

1

从我的经验和我的观点来看,答案很明确 - 不要添加is_new != 0。有几个原因,我会试着列出它们:

  • SQL约为解释你想做什么。添加条件也将告诉如何做到这一点。 MySQL的优化足以避免超出应有的工作范围。

  • 添加条件不会使您的查询更具可读性。删除它。它明确规定要更新is_new基于user_id

  • 添加条件的值有潜力伤性能。注意单词潜力 - 我不是说它会,但它可能会。如果你无法优化工作方式,为什么你可能会让它变慢?不要。就你而言,我们可能谈论的是糟糕的性能价值,但依然如此。

  • 添加条件将使MySQL做更多的工作。不多,但仍然 - 它会做更多。你并不需要它。

  • 在执行新的任何操作之前,MySQL会检查行是否确实发生了变化。如果is_new0,并且您希望再次将其设置为0- MySQL将会注意到并且它将跳过更新该行(写入操作比检查操作成本高得多,因此MySQL将执行该检查)。从手动

报价:

如果设置为它当前的值的列时,MySQL注意到这 并且不更新它。

相关的源代码,如果需要的话:here