2011-05-05 62 views
0

我剛剛完成創建一個新的分區表來替換舊的非分區表(爲保管而重命名)。我在創建時將舊錶中的最新數據複製到新表中,但仍有大約一半數據需要複製。問題是,這是一個不間斷的實時Web服務,每當我嘗試通過INSERT..SELECT複製一個塊時,它都堅持把它作爲一個原子事務處理(它消耗所有服務器的資源,減慢所有服務器的速度爬行,並可能危險地推送服務器,接近耗盡物理資源)。插入..每次插入後用commit提交到InnoDB表中?

只是要清楚:OldTable是MyISAM。 NewTable是InnoDB,並通過其主鍵「a」的範圍進行分區。兩個表都有相同的字段名稱。這些字段本身並不完全相同,但它們的區別在於,NewTable中的字段更大。

這是造成問題看起來像查詢:

INSERT INTO NewTable (a,b,c,d,e,f,g) 
SELECT a,b,c,d,e,f,g 
FROM OldTable 
WHERE a > 300000000 AND a <= 400000000 
order by a 

我想什麼它做的事:要麼每次插入後提交,或只是事務的完整性免除全部並允許髒讀的情況發生,如果他們發生。

鎖定NewTable(超出可能被插入的單個行)是不可接受的。鎖定OldTable很好,因爲無論如何,除了SQL將其複製到新表之外,其他都不再使用它了。

另外,有沒有辦法告訴MySQL以儘可能低的優先級完成它,並且只能在其相對空閒時間執行任務?

+0

如果你想要提交RBAR(行通過Agonizing Row),那麼你需要一個遊標。 – 2011-05-05 23:50:28

+0

有沒有中間的妥協?就像可能讓MySQL每隔一千或幾千行一樣提交?它不必在一行之後犯下......我只是不想等待它堅持嘗試在單個吞噬中做一百萬行,並且仍然有太多的總行數如果我將它從文本編輯器中複製並粘貼到MySQL的命令行客戶端中,那麼它們將以小於100萬的塊進行移動。 – Bitbang3r 2011-05-05 23:57:40

+0

我還沒有遇到SQL語法,它允許您爲批量插入/更新指定任意數字。 – 2011-05-06 00:00:40

回答

1

除了減少一次插入的行數之外,請嘗試將bulk_insert_buffer_size系統變量的值增加到更適合您的情況的值。默認值是8MB。