2012-03-01 5 views
24

Я пытаюсь ускорить массовую вставку в таблицу InnoDB путем временного отключения его индексов:Как отключить индекс в InnoDB

ALTER TABLE mytable DISABLE KEYS; 

Но это дает предупреждение:

+-------+------+-------------------------------------------------------------+ 
| Level | Code | Message              | 
+-------+------+-------------------------------------------------------------+ 
| Note | 1031 | Table storage engine for 'mytable' doesn't have this option | 
+-------+------+-------------------------------------------------------------+ 
1 row in set (0.00 sec) 

Как мы можем отключить индексы?

Какие существуют альтернативы, чтобы избежать использования индекса при выполнении объемных вставок?

Как мы можем ускорить процесс?

+0

Сколько у вас данных (в терминах строк и гигабайт)? И как вы его загрузите? – zerkms

+0

около 5 миллионов строк и около 1,2 ГБ. Благодарю. – fanchyna

+0

Связанный: http://stackoverflow.com/q/654594/632951 – Pacerier

ответ

26

Вы пробовали следующее?

SET autocommit=0; 
    SET unique_checks=0; 
    SET foreign_key_checks=0; 

С MySQL Ссылки https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

См раздел "Bulk Data Loading Советы"

+1

Я пытался это сделать. Но дело в том, как узнать, что индекс отключен или отключен? – fanchyna

+1

Я знаю, что оператор «EXPLAIN» может помочь понять инструкцию «SELECT», но как насчет оператора «LOAD DATA LOCAL INFILE»? Как я узнаю, что индекс работает при выполнении этой команды? Спасибо. – fanchyna

+0

@fanchyna, Disable/enable - глобальный параметр, а не сеанс. Используйте ['show keys in my_table'] (http://stackoverflow.com/questions/4980917/mysql-disable-keys/28667994#28667994), чтобы увидеть, являются ли индексы отключен или включен. – Pacerier

24

Существует очень хорошая причина, почему вы не можете выполнить DISABLE KEYS на таблицу InnoDB; InnoDB не предназначен для использования, и MyISAM.

В самом деле, вот что происходит, когда вы перезагружать туздЫшпр:

Вы увидите CREATE TABLE для таблицы MyISAM, сопровождающей блокировкой записи.

Перед тем, как все массовые вставки запущены, выполняется вызов ALTER TABLE ... DISABLE KEYS.

Что это значит, это отключить вторичные индексы в таблице MyISAM.

Затем, объемные вкладыши выполнены. Пока это делается, PRIMARY KEY и все UNIQUE KEYS в таблице MyISAM отключены. Перед UNLOCK TABLEs выполняется вызов ALTER TABLE ... ENABLE KEYS, чтобы перестроить все неидеальные индексы линейно.

IMHO эта операция не была закодирована в InnoDB Storage Engine, потому что все ключи в уникальном индексе поставляются с записью первичного ключа от gen_clust_index (aka Clustered Index). Это будет очень дорогостоящей операцией, поскольку для создания неидеального индекса потребуется время O (n log n) для извлечения каждого уникального ключа для присоединения к неповторимому ключу.

В связи с этим размещение предупреждений о попытке установить DISABLE KEYS/ENABLE KEYS на таблицу InnoDB намного проще, чем исключения для кодирования mysqldump для любых особых случаев, связанных с механизмами хранения, отличными от MyISAM.

+3

Благодарим вас за объяснение, но вопрос по-прежнему остается: как я могу избежать использования индекса при загрузке данных, чтобы уменьшить объем времени импорта. Спасибо. – fanchyna

+1

Что означает @RolandoMySQLDBA, означает, что вы не будете значительно сокращают время загрузки, отключая индексы в базе данных INNODB. Кластерные индексы представляют собой структуры данных на основе дерева (= журнал времени) сами по себе, ваши варианты строят весь индекс в nlogn или выполняют n logn в serts. Вы можете сэкономить немного на затраты на вставку, но на практике я уверен, что это очень мало; уже есть последовательная оптимизация вставки. –

+1

Я регулярно строю очень большие таблицы 'innodb' с большим количеством индексов (сотни гигабайт/10+ разных индексов). Существует огромное сокращение времени создания, когда я 'INSERT' в таблицы без индексов. Очевидно, что «огромный» во многом зависит от максимального размера вашей таблицы, количества и типа индексов, типов элементов данных и т. Д. Я обычно создаю таблицу без ничего, кроме первичного ключа (не нужно, если вы просто загружаете данные, которые уже имеют идентификатор первичного ключа), а затем строят индексы в конце. Вы можете не заметить разницу в строках 5MM и 1,5 ГБ, но по мере роста ваших таблиц вы будете. –

7

, чтобы снизить затраты на повторное вычисление индексов необходимо вставить данные либо с помощью DATA INFILE или с использованием Mysql многорядные Вставки, как

вставить в tbl_name (A, B, C) ЗНАЧЕНИЯ (1 , 2,3), (4,5,6), (7,8,9);

-> поэтому вставка нескольких строк с одним утверждением.

Количество строк, которые можно вставить одним оператором, зависит от настройки mysql max_allowed_packet.

+1

Ты уверен в этом? Итак, вы говорите нам, чтобы вставить миллион строк, используя ** ** инструкцию ** insert? – Pacerier

+0

Я не скажу вам вставлять «все данные» с одним утверждением, но вставлять сразу несколько строк. В моих приложениях я использовал 500-1000 строк на вставку без проблем. В основном это зависит от количества строк и количества данных, которые вы вставляете в строку. – staabm

+0

Итак, что хорошего? Вы решаете это путем проб и ошибок? – Pacerier

Смежные вопросы