我有一个看起来像这样的MySQL表:
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.6秒,28.8秒,44.4秒,76秒和128秒来创建。我还想添加一些索引。
当我将表创建为MyISAM时,不仅整个过程更快,创建每个后续索引所需的时间可能比前一个索引长一秒。
是什么给出的?这种行为有望吗?我在索引创建中做了一些有趣的事情吗?
对于它的价值,我在这个测试中使用MySQL 5.1.48 / OS X 10.6.8。
答案 0 :(得分:3)
这是基于how index creation happens in InnoDB的预期行为。
在高达5.0的MySQL版本中,在表上添加或删除索引 如果表有很多行,那么现有数据可能会非常慢。该 CREATE INDEX和DROP INDEX命令通过创建一个新的空来工作 使用请求的索引集定义的表。然后复制 现有的行逐个到新表,更新索引 去。以这种方式将条目插入索引中 键值未排序,需要随机访问索引节点, 并且远非最佳。从原始表中的所有行之后 复制后,将删除旧表,并使用名称重命名副本 原始表格。
从版本5.1开始,MySQL允许存储引擎创建或删除索引,而无需复制整个表的内容。但是,MySQL版本5.1中的标准内置InnoDB没有利用此功能。