MySQL: создание каждого индекса в таблице InnoDB занимает больше времени, чем в последнем - PullRequest
2 голосов
/ 14 июля 2011

У меня есть таблица 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;

и имеет 450 тыс. Строк.Но: я хочу добавить к нему несколько индексов:

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 в этом тесте.

1 Ответ

3 голосов
/ 14 июля 2011

Это ожидаемое поведение на основе того, как создание индекса происходит в InnoDB .

В версиях MySQL до 5.0 добавление или удаление индекса для таблицы с существующими данными может быть очень медленным, если в таблице много строк. Команды CREATE INDEX и DROP INDEX работают путем создания нового, пустого таблица определена с запрошенным набором индексов. Затем он копирует существующие строки новой таблицы, обновляя индексы по мере идет. Вставка записей в индексы таким образом, где значения ключей не отсортированы, требуется произвольный доступ к узлам индекса, и далеко не оптимально. После того, как все строки из исходной таблицы копируется, старая таблица удаляется, а копия переименовывается с именем оригинального стола.

Начиная с версии 5.1, MySQL позволяет механизму хранения создавать или удалять индексы, не копируя содержимое всей таблицы. Однако стандартная встроенная InnoDB в MySQL версии 5.1 не использует эту возможность.

...