2015-04-30 44 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