2015-04-30 193 views
0

我正在運行ETL過程並將數據流式傳輸到MySQL表中。提高SQL'Update'函數的速度 - 插入/刪除?

現在它正在通過網絡連接寫入(相當快),因此可能成爲瓶頸。

無論如何,這是一個基本的插入/更新功能。它是ID列表作爲主鍵/索引....然後是一些屬性。

如果找到一個新的ID,插入,否則,更新......你明白了。

當前正在做一個基於ID(索引)的「更新,否則插入」功能是13行/秒(這似乎很糟糕,對不對?)。對於上下文,這是將1000行與250k條記錄的數據庫進行比較。

當做一個「純」的插入所有的方法,作爲比較,已經加速到26行/秒的過程。

純粹的「插入」方法的事情是,我可以有20個並行連接「插入」一次...(20是Web主機最多允許的)...而任何「更新」功能不能有任何平行運行。

因此26×20 = 520r/s。大於13 r/s,特別是如果我可以調整某些東西,可以讓更多的數據並行傳輸。

我的問題是...鑑於插入與更新的巨大好處,有沒有一種方法來複制'更新'功能(我只想要給定ID的最新插入生存)....通過做一個大規模的插入,然後在事實之後運行一個刪除函數,刪除不是「最新」的重複ID?

這是容易實現的東西,還是經常出現的東西?

我還能做些什麼來確保此更新過程更快?我知道擺脫ETL工具和數據庫之間的'網絡連接'是一個開始,但還有什麼?這似乎是一個相當普遍的問題。

最終有20列,最大的可能是varchar(50)...我應該得到比13行/秒多得多的?

+0

你的「update,else insert」代碼看起來像什麼? –

回答

1

您的問題有很多可能的「答案」。

13 /秒 - 很多可以做...

INSERT ... ON DUPLICATE KEY UPDATE ...(「IODKU」),通常是做的最好的方式「更新,否則插入」(除非我不知道你是什麼意思是它)。

批次插入比一次插入一行快得多。 Optimal約爲100行,提供10倍加速。 IODKU也可以(通常)批量生產;請參閱VALUES()僞函數。

BEGIN; ......大量寫入...... COMMIT;顯着減少了事務開銷。

使用「分段」表收集事情更新可以有一個顯着的好處。這也包括批量「標準化」。

建築概要實時表干擾高速數據攝取。 Another blog covers Summary tables

標準化可用於消除抖動,從而縮小磁盤佔用空間。這對於減少Data Warehousing中的'Fact'表的I/O很重要。 (我指的是您的20 x VARCHAR(50)。)

RAID條帶化是硬件幫助。

RAID控制器上的Batter-Backed-Write-Cache使寫入看起來是瞬間的。

SSD加速I/O。

如果您提供了一些更具體的信息(SHOW CREATE TABLE,SQL等),我可以更具體。

1

在DBMS中執行此操作,並將其包裝在事務中。

爲了解釋:

  1. 加載數據到臨時表在MySQL儘可能以最快的方式。批量加載,插入,做任何工作。看看「加載數據infile」。

  2. 將臨時表外連接到目標表,然後插入目標表的PK列爲NULL的行。

  3. 將臨時表外連接到目標表,並更新那些目標表的PK列不爲空的行。

裹在步驟2和3開始/提交(或[開始交易] /提交對的交易。默認的行爲可能是自動提交,這將意味着你以後做數據庫的工作很多每個插入/更新,正確使用交易,每個塊只能完成一次工作