14.1.4 Syntaxe de INSERT
14.1 Manipulation de données : SELECT , INSERT , UPDATE , DELETE
14 Syntaxe des commandes SQL
Manuel de Référence MySQL 4.1 : Version Française
. Syntaxe de INSERT ... SELECT ->Syntaxe de INSERT DELAYED
|
14.1.4.2 Syntaxe de INSERT DELAYED
L'option
DELAYED
de la commande
INSERT
est une option spécifique
à MySQL très utile si vos clients ne peuvent pas attendre que
INSERT
se
termine. C'est un problème fréquent quand on utilise MySQL pour des logs, mais
aussi quand on utilise souvent des commandes
SELECT
ou
UPDATE
qui prennent beaucoup de temps.
DELAYED
a été ajouté à MySQL dans la version
3.22.15. C'est une extension de MySQL au ANSI SQL 92.En utilisant
INSERT DELAYED
, le client reçoit immédiatement un aquitement,
et la ligne sera insérée quand la table ne sera plus utilisée par un autre thread.
Un autre avantage de
INSERT DELAYED
est que les insertions des clients sont
regroupés, et écrits d'un seul bloc. C'est beaucoup plus rapide que de faire des
insertions séparés.
Il y a quelques contraintes à l'utilisation de
DELAYED
:
-
INSERT DELAYED
ne fonctionne qu'avec les tables
MyISAM
et
ISAM
.
Pour les tables
MyISAM
, s'il n'y a plus de blocs libres au milieu du
fichier de données, les
SELECT
et
INSERT
simultanés sont supportés.
Dans ces circonstances, vous n'aurez que très rarement besoin de
INSERT DELAYED
avec
MyISAM
. Tables
MyISAM
.
-
INSERT DELAYED
doit être utilisé uniquement avec les commandes
INSERT
qui spécifie une liste de valeur. C'est le cas depuis MySQL 4.0.18. Le serveur
ignore
DELAYED
pour les commandes
INSERT DELAYED ... SELECT
.
-
Le serveur ignore
DELAYED
dans les commandes
INSERT DELAYED ... ON DUPLICATE UPDATE
.
-
Comme la commande s'exécute immédiatement, sans que la ligne ne soit
insére, vous ne pouvez pas utiliser
LAST_INSERT_ID()
pour lire la valeur que
la colonne
AUTO_INCREMENT
va générer.
-
Les lignes
DELAYED
ne sont visibles par les commandes
SELECT
que
lorsqu'elles ont été réellement insérées.
Actuellement, les lignes en attente sont uniquement stockées en mémoire tant
qu'elle ne sont pas insérées dans la table. Cela signifie que si on tue
mysqld
violemment, (
kill -9
) ou si
mysqld
meurt accidentellement, toutes
les lignes en attente qui n'auront pas été écrites sur le disque seront perdues !
Les paragraphes suivants décrivent en détail ce qu'il se passe quand on utilise
l'option
DELAYED
dans une requête
INSERT
ou
REPLACE
.
Dans cette description, ``thread'' est un thread qui reçoit une commande
INSERT DELAYED
ans ``handler'' est un thread qui gère toutes les opérations
de
INSERT DELAYED
pour une table donnée.
-
Quand un thread exécute une opération
DELAYED
sur une table, un thread de gestion
est créé pour exécuter toutes les opérations
DELAYED
pour cette table - si ce
thread de gestion n'existe pas.
-
Le thread vérifie que a déjà reçu un verrou
DELAYED
; sinon, il dit au thread de
gestion de le faire. le verrou
DELAYED
peut être obtenu même si
d'autres threads ont des verrous
READ
ou
WRITE
sur la table. Cependant
le gestionnaire attendra que tous les verrous
ALTER TABLE
ou
FLUSH TABLES
soient finis pour s'assurer que la structure de la table est à jour.
-
Le thread exécute une opération
INSERT
, mais plutôt que d'écrire la ligne
dans la table, il va placer une copie de la ligne finale dans une file d'attente
gérée par le thread de gestion. Le programme client est avertit de toutes les erreurs
de syntaxe.
-
Le client ne peut pas faire de rapport sur le nombre de duplicata ou sur la valeur
de
AUTO_INCREMENT
de la ligne enregistrée; il ne peut pas les obtenir du
serveur, car le
INSERT
est validé avant que l'opération d'insert n'ait été
effectuée. Si vous utilisez l' API C, la fonction
mysql_info()
ne retourne
pas de valeur intéressante, pour la même raison.
-
Le journal de modification est mis à jour par le thread de gestion au moment où la
ligne est insérée dans la table. Si plusieurs lignes sont insérées en même temps,
le journal des modifications est mis à jour quand la première ligne est insérée.
-
Une fois que toutes les lignes
delayed_insert_limit
sont écrites, le gestionnaire
vérifie si des requêtes
SELECT
sont en attente, et si c'est le cas, il leur
permet de s'exécuter avant de continuer.
-
Quand le thread de gestion n'a plus de ligne dans sa file, la table est déverrouillée.
Si aucun
INSERT DELAYED
n'est reçu avant
delayed_insert_timeout
secondes,
le gestionnaire s'arrête.
-
Si plus de
delayed_queue_size
lignes sont déjà en attente d'un gestionnaire de file
donné, le thread qui demande le
INSERT DELAYED
doit attendre qu'il y ait une place
dans la file. Cela permet d'être sûr que
mysqld
n'utilisera pas toute
la mémoire pour la mémoire des files d'attente d'insertions retardés.
-
Le thread de gestion apparaîtra dans la liste des processus de MySQL avec
delayed_insert
dans la colonne
Command
. Il sera tué si on exécute une commande
FLUSH TABLES
ou si on le tue avec
KILL thread_id
. Cependant, il commencera par stocker toutes les
lignes en attente dans la table avant de sortir. Pendant ce temps, il n'acceptera aucune
commande
INSERT
d'aucun autre thread. Si on exécute une commande
INSERT DELAYED
après cela, un nouveau thread de gestion sera créé.Il faut noter que les commandes
INSERT DELAYED
ont une plus grande priorité que
les commandes
INSERT
normales si un gestionnaire de
INSERT DELAYED
existe déjà! les autres commandes de modification devront attendre que la file d'attente
de
INSERT DELAYED
soit vide, que quelqu'un tue le gestionnaire (avec
KILL thread_id
),
ou que quelqu'un exécute
FLUSH TABLES
..
-
Les variables suivantes fournissent des informations relatives à la commande
INSERT DELAYED
:
Variable
|
Signification
|
Delayed_insert_threads
|
Nombre de threads de gestion
|
Delayed_writes
|
Nombre de lignes écrites avec
INSERT DELAYED
|
Not_flushed_delayed_rows
|
Nombre de lignes en attente d'être écrites.
|
On peut voir ces variables avec la commande
SHOW STATUS
ou en exécutant la commande
mysqladmin extended-status
.
Il faut noter que
INSERT DELAYED
est plus lent qu'un INSERT normal si la table n'est pas
utilisée. L'utilisation d'un thread de gestion séparé pour chaque table sur lesquelles on utilise
INSERT DELAYED
rajoute également une surcharge au serveur. Ce qui signifie qu'il vaut
mieux utiliser
INSERT DELAYED
uniquement quand c'est vraiment nécessaire!
|