2012-05-28 60 views
1

我有一個2.37億行的MySQL表。我想處理所有這些行並用新值更新它們。如何高效處理MySQL表的所有行?

我有順序編號的,所以我可以只使用select陳述了很多:

where id = '1' 
where id = '2' 

這是Sequentially run through a MYSQL table with 1,000,000 records?提到的方法。

但我想知道是否有更快的方式使用光標,可用於順序讀取大文件而無需將全套內容加載到內存中。我看到它的方式,光標將比運行數百萬條select語句更快地將數據返回到可管理的塊中。

+3

你看過DBI嗎? – Mat

+1

你鏈接的方法是不相關的/如果你把它作爲許可證循環'where id ='1'',''2'',...你看錯了。 –

+3

您希望更新數據的值是什麼?它們與數據庫中已有的東西有什麼關係?如果是這樣,請直接使用它們。如果沒有,請將您的新數據插入臨時表中,然後進行更新。 – eggyal

回答

7

理想情況下,您將獲得DBMS爲您完成工作。您將SQL語句設置爲僅在數據庫中運行,而不是將數據返回給應用程序。除此之外,這節省了向客戶端發送的2.37億條消息的開銷,並將2.37億條消息返回給服務器。

這是否可行取決於更新的性質:

  • 的DBMS能夠確定新的價值觀應該是什麼?
  • 您能否將必要的數據導入數據庫,以便DBMS可以確定新值應該是什麼?
  • 2.37億行中的每一行是否會被更改,或者只是一個子集?
  • DBMS可以用來確定子集嗎?
  • id值中的任何一個都會被改變嗎?

如果id值永遠不會改變的,那麼你可以安排將數據劃分爲管理的子集,爲「管理」的任何靈活定義。

您可能需要考慮事務邊界;這一切都可以在一次交易中完成,而不會將日誌吹出來?如果您以子集而不是單個原子事務進行操作,那麼如果您的驅動進程崩潰時處理了1.97億行,那麼您將執行什麼操作?或者DBMS在那個時候崩潰了?你將如何知道在哪裏恢復操作來完成處理?

+0

我確實可以編寫一個單一的sql語句(所有信息都在db中)。然而,這是一個生產數據庫,我擔心擴展鎖定(我使用innodb,所以也許這不是問題?)我確實需要更新表中的每條記錄。目前我傾向於使用索引一次抓取1000行。要回答您的最終問題,索引值不會發生變化。 – Eric

+1

只要您的企業不會基於最初2億行的後更新值和最新3700萬行的預更新值做出錯誤決定,那麼每次分批更新1000次的涓流更新是合理的。 「id」列不會改變的事實大大簡化了您的生活。確保你使用明確的事務,並且保存記錄,不知何故,哪些行已被更新。也許在數據庫中添加一個表來記錄哪些行已被處理,因此運行1000行更新,然後更新新表以反映這些更改,然後提交。 –

+0

這是一個非常明智和深思熟慮的答案。 +1爲明確和權威的語言。謝謝。 –