2011-07-14 42 views
2

我有一個MySQL表看起來像這樣:MySQL的:對InnoDB表的每個索引需要較長時間才能創造出比過去的

CREATE TABLE my_facts (
    `id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, 
    `account_id` int(11) NOT NULL, 
    `asked_on` date NOT NULL, 
    `foo_id` int(11) NOT NULL, 
    `bar_id` int(11) NOT NULL, 
    `baz_id` int(11) NOT NULL, 
    `corge_id` int(11) NOT NULL, 
    `grault_id` int(11) NOT NULL, 
    `flob_id` int(11) NOT NULL, 
    `tag_id` int(11) NOT NULL) 
ENGINE=InnoDB; 

,並具有450K行。但我想幾個指標添加到它:

CREATE INDEX `k_account_foo_id` ON `my_facts` (`account_id`, `asked_on`, `foo_id`, `tag_id`); 

CREATE INDEX `k_account_bar_id` ON `my_facts` (`account_id`, `asked_on`, `bar_id`, `tag_id`); 

CREATE INDEX `k_account_baz_id` ON `my_facts` (`account_id`, `asked_on`, `baz_id`, `tag_id`); 

CREATE INDEX `k_account_corge_id` ON `my_facts` (`account_id`, `asked_on`, `corge_id`, `tag_id`); 

CREATE INDEX `k_account_grault_id` ON `my_facts` (`account_id`, `asked_on`, `grault_id`, `tag_id`); 

我的問題是,每個指標需要更長的時間來創造出比過去的 - 這似乎是一個幾何軌跡。爲了創建索引,需要11.6s,28.8s,44.4s,76s和128s。我想添加更多的索引。

當我創建表爲MyISAM時,不僅整個過程快得多,創建每個後續索引所需的時間可能比先前的索引長一秒。

什麼給?預期這種行爲?我在創建索引時做了些有趣的事情嗎?

爲了什麼是值得的,我在這個測試中使用了MySQL 5.1.48/OS X 10.6.8。

回答

3

這是基於how index creation happens in InnoDB的預期行爲。

在MySQL版本到5.0,添加或桌子上的 與現有的數據刪除索引可以是非常慢如果表中有許多行。 CREATE INDEX和DROP INDEX命令的工作原理是創建一個新的空的 表,其中包含所請求的一組索引。然後它將 現有行復制到新表中,更新 的索引。以這種方式在索引中插入條目(其中 鍵值未被排序)需要對索引節點的隨機訪問 並且遠非最佳。在複製原始表中的所有行 之後,將刪除舊錶並將該副本重命名爲原始表的名稱 。

從版本5.1開始,MySQL允許存儲引擎創建或刪除索引而不復制整個表的內容。然而,MySQL版本5.1中的標準內置InnoDB並沒有利用這種能力。

+0

啊,謝謝!現在完全合理。所以,最好是創建表,添加鍵,禁用鍵,插入數據,然後重新啓用鍵? – Nate

+1

我不知道什麼是最快的,但我只是創建一個新的表,其中包含所有您想要的索引,並將所有行復制到「INSERT INTO ... SELECT」查詢中,然後重命名。 –

相關問題