Le temps d'insertion d'une ligne est constitué comme ceci :
Connexion : (3)
Envoi au serveur : (2)
Analyse de la requête : (2)
Insertion de la ligne : (1 x taille de la ligne)
Insertion des index : (1 x nombre d'index)
Fermeture : (1)
où les nombres représentent une partie proportionnelle du temps total. Le calcul ne prend pas en compte les coûts d'administration initiaux de l'ouverture des tables (qui est fait une fois pour chaque requête simultanée).
La taille de la table ralentit les opérations d'insertion des
index par un facteur de log N (B-tree
s).
Quelques méthodes pour accélérer les insertions :
Si vous insérez plusieurs lignes depuis le même client, en
même temps, utilisez les valeurs multiples de la commande
INSERT
. C'est bien plus rapide (et
parfois beaucoup plus rapide) que d'utiliser des commandes
INSERT
distinctes. Si vous ajoutez des
données dans une table non vide, vous pouvez ajuster la
variable bulk_insert_buffer_size
pour
l'accélérer encore plus. See
Section 13.5.3.18, « Syntaxe de SHOW VARIABLES
».
Si vous insérez de nombreuses lignes depuis différents
clients, vous pouvez accélérer les insertions en utilisant
la commande INSERT DELAYED
. See
Section 13.1.4, « Syntaxe de INSERT
».
Avec les tables MyISAM
, vous pouvez
insérer des lignes en même temps que vous utilisez des
commandes SELECT
, du moment qu'il n'y a
pas d'effacement de ligne dans la table.
Lorsque vous chargez une table depuis un fichier texte,
utilisez la commande LOAD DATA INFILE
.
Elle est généralement 20 fois plus rapide que
l'équivalent en commandes INSERT
. See
Section 13.1.5, « Syntaxe de LOAD DATA INFILE
».
Il est possible, avec un peu de travail supplémentaire,
d'accélérer encore la vitesse des commandes LOAD
DATA INFILE
. Utilisez la procédure standard :
Créez optionnellement une table avec CREATE
TABLE
. Par exemple, en utilisant
mysql
ou Perl DBI
.
Exécutez une commande FLUSH TABLES
ou la commande en ligne shell mysqladmin
flush-tables
.
Utilisez myisamchk --keys-used=0 -rq
/path/to/db/tbl_name
. Cela va supprimer
l'utilisation des index dans la table.
Insérez vos données dans la table, avec LOAD
DATA INFILE
. Les index ne seront pas
modifiés, et donc, très rapides.
Si vous allez uniquement lire la table dans le futur,
utilisez myisampack
pour la réduire
de taille. See Section 14.1.3.3, « Caractéristiques des tables compressées ».
Re-créez les index avec myisamchk -r -q
/path/to/db/tbl_name
. Cette commande va créer
l'arbre d'index en mémoire, avant de l'écrire sur le
disque, ce qui est bien plus rapide, car il n'y a que
peu d'accès disques. L'arbre final sera aussi
parfaitement équilibrés.
Exécutez une commande FLUSH TABLES
ou utilisez la commande en ligne shell
mysqladmin flush-tables
.
Notez que la ocmmande LOAD DATA INFILE
fait aussi les optimisations ci-dessus, si vous faites les
insertions dans une table vide. La différence principale
avec la procédure ci-dessus est que vous pouvez laisser
myisamchk
allouer plus de mémoire
temporaire pour la création d'index, que vous ne pourriez
le faire pour chaque recréation.
Depuis MySQL 4.0 vous pouvez aussi utiliser ALTER
TABLE tbl_name DISABLE KEYS
au lieu de
myisamchk --keys-used=0 -rq
/path/to/db/tbl_name
et ALTER TABLE
tbl_name ENABLE KEYS
au lieu de myisamchk
-r -q /path/to/db/tbl_name
. De cette fa¸on, vous
pouvez aussi éviter l'étape FLUSH
TABLES
.
Vous pouvez accélérer les insertions qui sont faites avec plusieurs requêtes en verrouillant vos tables :
mysql>LOCK TABLES a WRITE;
mysql>INSERT INTO a VALUES (1,23),(2,34),(4,33);
mysql>INSERT INTO a VALUES (8,26),(6,29);
mysql>UNLOCK TABLES;
La principale différence de vitesse est que l'index de
buffer est écrit sur le disque une fois, après toutes les
insertions INSERT
terminées.
Normalement, il aurait du y avoir de nombreuses écritures,
une pour chaque commande INSERT
. Le
verrouillage n'est pas nécessaire si vous pouvez insérer
toutes les lignes d'une seule commande.
Pour les tables transactionnelles, vous devriez utiliser
BEGIN/COMMIT
au lieu de LOCK
TABLES
pour accélérer les opérations.
Le verrouillage va aussi réduire le nombre total de tests de connexions, mais le temps d'attente maximum de certains threads va augmenter (car il va y avoir la queue pour les verrous). Par exemple :
thread 1 fait 1000 insertions thread 2, 3, et 4 font 1 insertion thread 5 fait 1000 insertions
Si vous ne voulez pas utiliser le verrouillage, les threads 2, 3 et 4 auront fini avant les 1 et 5. Si vous utilisez le verrouillage, 2, 3 et 4 me finiront probablement pas avant 1 ou 5, mais la durée globale de l'opération sera 40% plus courte.
Comme les commandes INSERT
,
UPDATE
et DELETE
sont
très rapides avec MySQL, vous obtiendrez de meilleures
performances générales en ajoutant des verrous autour de
toutes vos opérations de 5 insertions o modifications
simultanées. Si vous faîtes de très nombreux insertions
dans une ligne, vous pouvez utiliser LOCK
TABLES
suivi de UNLOCK TABLES
une fois de temps en temps (par exemple, toutes les 1000)
pour permettre aux autres threads d'accéder à la table.
Cela vous donnera quand même une bonne accélération.
Bien sur, LOAD DATA INFILE
reste bien
plus rapide pour charger les données.
Pour accélérer LOAD DATA INFILE
et
INSERT
, agrandissez le buffer de clé.
See Section 7.5.2, « Réglage des paramètres du serveur ».
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.