2012-08-31 97 views
2

如果我想更新具有相同值的字段。爲表中所有行更新一個具有相同常量的字段值...更好的表現方式?

例如,表筆,用severals列:A,B,C

是否更好地運行這樣一句話:

UPDATE `T` SET `B` = '0'; 

這一個:

UPDATE `T` SET `B` = '0' WHERE `B` <> '0'; 

我第一個想到的可能會更快(即使我有基於B指數)?

如果我有百萬行的..會是長或真快應用此更新?

(我嘗試搜索一個現有的類似問題......但它與我使用的關鍵字相當困難......太多不同的問題......不要猶豫,指我一個好的......)

+1

'EXPLAIN'顯示每條語句的含義是什麼? – Kermit

+0

@njk:嗡嗡聲..我不知道..不是專家用mysql ...我看... – Whiler

+0

所有取決於你有多少'B = 0'。如果緩存大部分數據,更新數據庫可能很昂貴。 – Grzegorz

回答

2

的相對性能取決於WHERE B <> 0選擇性。

  • WHERE子句將執行全表掃描。

  • 對B無指數將執行全表掃描。

  • B上的索引具有較低的選擇性,即許多命中會產生較高的隨機I/O率,因爲在索引中找到的行被更新。在大多數系統中,這將是一個性能瓶頸。如果選擇性非常低,那麼您可能會得到全表掃描的很大一部分,但是僞隨機而不是順序 - 這是最糟糕的情況。這可能會在查詢計劃生成期間進行優化,並由全表掃描取代。

  • 具有高選擇性,即幾命中仍然會創建隨機I/O,但只短短的必要 - 這是最好的情況。

所以根據需要更新的行的百分比,就應該全表掃描(=無WHERE),並有針對性的方法(= WHERE索引)

+0

謝謝對於不同的場景 – Whiler

1

恕我直言,第一個會更快...其中的值不是目標值

據我所知MySQL只自動更新列 - 所以是一個雙重檢查的「值」,它會遍歷EVER在行上。 你的第二個方法是將迭代兩次,如果沒有這是完全沒有好檢查與where子句的索引。

+1

這正是我**認爲的** ... – Whiler

1

除了性能,你應該知道之間的選擇關於實際情況的差異。

第一個選項需要MySQL鎖定所有行,第二個選項只需要行鎖在那裏B <> '0'。使用InnoDB當存在B的索引時,MySQL能夠做到這一點。

當你併發交易你的發佈選項是不一樣的。第一個保證提交後的每一行是b=0。第二個僅保證提交後b<>0的每一行都設置爲0。但是另一個交易可以將b=0的某行同時更改爲另一個值。

所以即使你不關心不同的行爲,你應該關心整個性能,當你有併發交易。這可能是第一個選項更快,但它阻止訪問此錶行的所有其他事務,而第二個選項並非如此。

+0

感謝這些細節 – Whiler

相關問題