2011-04-14 69 views
1

生產數據庫中有大量數據,我想用批數據進行更新,而表中的數據仍可供最終用戶使用。更新可以插入新行或更新現有行。具體的表格大約有50M行,更新將在每批「批量」100k到1M行之間。我想要做的是以低優先級插入替換。換句話說,我希望數據庫能夠緩慢地進行批量導入,而不會影響同時發生在相同磁盤主軸上的其他查詢的性能。更復雜的是,更新數據的索引很大。 8個跨越多列的b-tree索引,以促進各種查找,這會增加導入的相當多的開銷。在生產數據庫中更新大量數據

我曾經想過把插入物分成1-2k個記錄塊,然後讓外部腳本加載數據只是在每個插入點之間暫停幾秒鐘,但這真是一種嗜好的恕我直言。另外,在1M記錄批次期間,如果不需要,我真的不想添加500-1000次2秒暫停以增加20-40分鐘的額外加載時間。任何人有更好的方式來做到這一點的想法?

+0

等待低活動期,或如您所建議的,使批次小得多。 – Randy 2011-04-14 21:34:09

回答

2

我已經處理了一個使用InnoDB和數億行的類似場景。如果要將最終用戶的風險降至最低,則使用限制機制進行批處理是方法。我會嘗試不同的停頓時間,看看有什麼適合你的。對於小批次,您可以獲得相應調整的好處。如果按順序運行,您可能會發現不需要任何暫停。如果您的最終用戶使用更多的連接,那麼他們自然會獲得更多的資源。

如果您使用的是MyISAM,則有UPDATE的LOW_PRIORITY選項。如果您使用InnoDB進行復制,請務必檢查它是否因爲額外負載而落後。顯然它運行在一個單一的線程中,這對我們來說是一個瓶頸。因此,我們對節流機制進行了編程,以檢查複製到底有多遠,並根據需要暫停。

0

檢查此鏈接:http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html我會做的是編寫一個腳本,當MySQL顯示Threads_running或連接在一定數量下時,腳本將執行您的批量更新。希望你有某種測試服務器,你可以確定這些服務器變量的好數字閾值。還有很多其他的服務器狀態變量。也許通過Innodb_data_pending_writes數字來控制執行?讓我們知道什麼適合你,它是一個有趣的問題!

2

INSERT DELAYED可能是你需要的。從鏈接的文檔:

delayed_insert_limit行寫入每一次,處理器檢查是否任何SELECT語句仍懸而未決。如果是這樣,它允許這些在繼續之前執行。

+0

我一直在看這個,但文檔說它會忽略延遲,如果有一個重複的密鑰更新。 – Zak 2011-04-14 22:40:24

+0

還有一個[REPLACE DELAYED](http://dev.mysql.com/doc/refman/5.0/en/replace.html)。不幸的是,在這種情況下DELAYED的工作原理沒有解釋。 – Oswald 2011-04-14 23:05:41