web-dev-qa-db-fra.com

Comment désactiver l'index dans innodb

J'essaie d'accélérer l'insertion en bloc dans une table InnoDB en désactivant temporairement ses index:

ALTER TABLE mytable DISABLE KEYS;

Mais cela donne un avertissement:

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

Comment désactiver les index?

Quelles alternatives existe-t-il pour éviter d'utiliser l'index lors de l'insertion en bloc?

Comment pouvons-nous accélérer le processus?

30
fanchyna

Avez-vous essayé ce qui suit?

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

À partir des références MySQL https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

Voir la section " Conseils de chargement de données en masse "

31
lurkerbelow

Il y a une très bonne raison pour laquelle vous ne pouvez pas exécuter DISABLE KEYS sur une table InnoDB; InnoDB n'est pas conçu pour l'utiliser, et MyISAM l'est.

En fait, voici ce qui se passe lorsque vous rechargez un mysqldump:

Vous verrez un CREATE TABLE pour une table MyISAM suivie d'un verrou en écriture.

Avant d'exécuter toutes les insertions en bloc, un appel à ALTER TABLE ... DISABLE KEYS est fait.

Cela permet de désactiver les index secondaires dans la table MyISAM.

Ensuite, des insertions en masse sont effectuées. Pendant ce temps, la CLÉ PRIMAIRE et toutes les CLÉS UNIQUES de la table MyISAM sont désactivées. Avant le UNLOCK TABLEs, un appel ALTER TABLE ... ENABLE KEYS est fait afin de reconstruire tous les index non uniques linéairement.

À mon humble avis, cette opération n'a pas été codée dans le moteur de stockage InnoDB car toutes les clés d'un index non unique sont fournies avec l'entrée de clé primaire de gen_clust_index (aka Clustered Index). Ce serait une opération très coûteuse car la construction d'un index non unique nécessiterait un temps d'exécution O (n log n) pour récupérer chaque clé unique pour l'attacher à une clé non unique.

À la lumière de cela, publier un avertissement sur les tentatives de DISABLE KEYS/ENABLE KEYS sur une table InnoDB est beaucoup plus facile que de coder des exceptions à mysqldump pour tous les cas particuliers impliquant des moteurs de stockage non MyISAM.

29
RolandoMySQLDBA

pour réduire les coûts de recalcul des index, vous devez insérer les données à l'aide de DATA INFILE ou à l'aide de Mysql Multi Row Inserts, comme

INSÉRER DANS tbl_name (a, b, c) VALEURS (1,2,3), (4,5,6), (7,8,9);

-> insérant ainsi plusieurs lignes avec une seule instruction.

Le nombre de lignes que l'on peut insérer avec une instruction dépend du paramètre max_allowed_packet mysql.

8
staabm

Un peu tard mais ... peu importe ... oubliez toutes les réponses ici, ne désactivez pas les index, il n'y a aucun moyen, déposez-les simplement ALTER TABLE nom_table DROP INDEX whatever, insérez les données en bloc, puis ALTER TABLE nom_table ADD INDEX whatever (whatever); le temps de recréation des index est de 1% de l'insert en vrac avec des index dessus, comme 400000 lignes ont pris 10 minutes avec les index et comme 2 secondes sans eux ..., cheers ...

5
KciNicK