| 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. 
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!
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
  : 
On peut voir ces variables avec la commande  
SHOW STATUS
  ou en exécutant la commande 
  
mysqladmin extended-status
 .
| 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. |  |