2011-09-18 131 views

回答

6

不幸的是,你可能做得不多。當插入一個新列時,MySQL會複製一張表並在其中插入新數據。您可以發現更快做

CREATE TABLE new_table LIKE old_table; 
ALTER TABLE new_table ADD COLUMN (column definition); 
INSERT INTO new_table(old columns) SELECT * FROM old_table; 
RENAME table old_table TO tmp, new_table TO old_table; 
DROP TABLE tmp; 

這不是我的經驗,但我聽說別人已經成功。您也可以在插入之前嘗試在new_table上禁用索引,然後再重新啓用。請注意,在這種情況下,您需要注意不要丟失在轉換期間可能插入old_table的任何數據。

或者,如果您的問題在更改過程中影響用戶,請檢查出pt-online-schema-change,它可以巧妙地使用觸發器來執行ALTER TABLE語句,同時保持表格被修改可用。 (請注意,這不會然而加快這一進程。)

+0

小時和等待時間沒有做到這一點。最後創建了該表的副本,添加了新列,刪除了索引並複製了jiffy –

+0

+1中的記錄以獲得建議。爲我工作,雖然有兩個小改變,我會建議。 RENAME new_table TO tmp,old_table TO new_table;應該是 RENAME table new_table TO old_table,old_table TO tmp; – pinaki

+0

@pinaki謝謝。這當然是我的意思。 –

0

邁克爾的解決方案可能會加速一些事情,但也許你應該看看數據庫,並嘗試將大表分解爲更小的表。看看這個:link。規範化數據庫表格可能會爲您節省將來的時間。

+0

我們在LINUX上使用MySQL,MYISAM。我的意思是在表格中插入一個新類型。 –

+0

這應該真的發佈爲評論,因爲它不回答問題。 –

+0

@coder - 什麼讓你覺得我的數據庫沒有正常化? –

1

通常新的行插入意味着有很多索引..所以我會建議重新考慮索引。

+0

是的,我可以刪除索引,再次添加新列和重新索引。這會更快,我認爲 –

3

有,你可以做,使這個快四個主要方面:

  1. 如果使用innodb_file_per_table原始表可在高度分散文件系統,所以你可以先嚐試對它進行碎片整理。

  2. 使緩衝池儘可能大,所以更多的數據,特別是二級索引都適合它。

  3. 使innodb_io_capacity足夠高,可能比平常高,這樣插入緩衝區合併和修改頁面的刷新將更快發生。需要具有InnoDB插件或5.5及更高版本的MySQL 5.1。

  4. 帶有InnoDB插件和MySQL 5.5及更高版本的MySQL 5.1支持快速更改表。使得速度更快的事情之一是添加或重建索引,這些索引不是唯一的,也不是外鍵。所以你可以這樣做:

A. ALTER TABLE添加你的列,刪除你不是FKs的非唯一索引。

B. ALTER TABLE添加您的非唯一非FK索引。

這應該提供以下好處:

a。步驟A中緩衝池的使用較少,因爲緩衝池只需要保存一些索引,即唯一或FK中的索引。在此步驟中索引會隨機更新,因此如果它們不能完全適應緩衝池,性能會變得更糟。所以你重建的機會會更快。

b。快速更改表通過對條目進行排序然後構建索引來重建索引。這是更快的,並且還會產生一個頁面填充因子較高的索引,因此開始時它會更小更快。

主要的缺點是,這是分兩步進行的,在第一步之後,你不會有一些可能需要的索引以獲得良好的性能。如果這是一個問題,您可以嘗試複製到新的表格方法,首先對新表格使用唯一的FK索引,然後再添加非唯一的索引。

它僅在MySQL 5.6中提供,但http://bugs.mysql.com/bug.php?id=59214中的功能請求提高了插入緩衝區更改刷新到磁盤的速度,並限制了緩衝池可以佔用多少空間。這可能是大型工作的性能限制。插入緩衝區用於緩存對二級索引頁面的更改。

我們知道,這有時仍然是令人沮喪的緩慢和一個真正的在線修改表非常非常希望

這是我個人的看法。對於Oracle的官方觀點,請聯繫Oracle公關人員。

James Day,MySQL高級主要支持工程師,Oracle