Le moteur de table MEMORY (HEAP)
Le moteur de stockage MEMORY crée des tables dont le contenu est stocké en mémoire. Avant MySQL 4.1, les tables MEMORY étaient appelées des tables HEAP. Depuis 4.1, HEAP est un synonyme de MEMORY, et MEMORY est le terme recommandé.
Chaque table MEMORY est associée à un fichier sur le disque. Le fichier a le nom de la table, et pour extension .frm pour indiquer la définition de la table. Pour spécifier explicitement que vous voulez une table MEMORY, indiquez l'option ENGINE ou TYPE :
Les tables HEAP utilisent un index de hachage, et sont stockées en mémoire. Elles sont très rapides, mais si MySQL plante, vous perdrez toutes vos données. La table continuera d'exister car leur définition est stockée sur le serveur, dans le fichier .frm mais le contenu sera perdu au redémarrage du serveur. Les tables HEAP sont très pratiques pour être des tables temporaires. Voici un exemple qui montre comment créer, utiliser et détruire une table MEMORY :
Les tables MEMORY ont les caractéristiques suivantes :
Les données pour les tables HEAP sont alloués par petits blocs. Les tables sont 100% dynamiques (en insertion). Aucune zone de débordement ou d'espace de clé supplémentaire n'est nécessaire. Les lignes effacées sont placées dans une liste, prêtes à être réutilisées.
Les tables MEMORY peuvent avoir jusqu'à 32 index par table, 16 colonnes par index, et un maximum de 500 pour la tailles des clés.
Avant MySQL 4.1, le moteur MEMORY n'implémentait que des index hash. Depuis MySQL 4.1, Les index hash sont le type par défaut, mais vous pouvez spécifier explicitement que l'index MEMORY doit être de type HASH ou BTREE en ajoutant la clause USING :
Les caractéristiques générales des hash et B-tree sont décrites dans la section, « Comment MySQL utilise les index ».
Vous pouvez avoir des clés non-uniques dans une table MEMORY. (C'est une fonctionnalité rare pour les index hash).
Si vous avez un index hash sur une table HEAP avec un haut degré de duplication (de nombreux valeurs d'index contiennent la même valeur), les modifications dans cette table peuvent affecter les valeurs des clés et toutes les suppressions seront plus lentes. Le facteur de ralentissement est proportionnel au degré de duplication (ou inversement proportionnel à la cardinalité). Depuis la version 4.1, MySQL supporte les index BTREE les tables HEAP, que vous pouvez utiliser pour éviter le problème.
Les tables HEAP utilisent un format de ligne fixe.
HEAP ne supporte pas les colonnes de type BLOB/TEXT.
HEAP ne supporte pas les colonnes de type AUTO_INCREMENT.
Avant MySQL 4.0.2, HEAP ne supportait les index sur les valeurs NULL.
Les tables HEAP sont partagées entre tous les clients (comme une autre table).
La caractéristique des tables MEMORY qui fait que les tables sont stockées en mémoire est partagée avec les tables internes que le serveur crée à la volée lors du traitement des requêtes. Cependant, les tables internes ont aussi la capacité d'être converties en tables disques automatiquement, si elles deviennent trop grandes. La taille limite est déterminée par la valeur de tmp_table_size. Les tables MEMORY ne peuvent pas être converties en tables disques. Pour vous assurer que vous ne faîtes rien de dangereux pour le serveur, vous pouvez utiliser la variable système max_heap_table_size pour imposer une taille maximale aux tables MEMORY. Pour des tables individuelles, vous pouvez utiliser l'option de table MAX_ROWS avec la commande CREATE TABLE.
Vous avez besoin de suffisamment de mémoire pour accepter toutes les tables HEAP que vous allez utiliser simultanément.
Pour libérer de la mémoire, vous devez exécuter la commande DELETE FROM heap_table, TRUNCATE heap_table ou DROP TABLE heap_table.
Si vous voulez remplir les tables MEMORY au lancement du serveur MySQL, vous pouvez utiliser l'option --init-file. Par exemple, vous pouvez mettre les commandes telles que INSERT INTO ... SELECT et LOAD DATA INFILE pour lire des données dans une source de données persistante. See Section 5.2.1, « Options de ligne de commande de mysqld ».
Si vous utilisez la réplication, les tables MEMORY du maître se vident à l'extinction. Rependant, un esclave peut ne pas s'apercevoir que ces tables ont été vidées, et il risque de retourner des données invalides si vous l'utilisez. Depuis MySQL 4.0.18, lorsqu'une table MEMORY est utilisée sur le maître, il émet une commande DELETE FROM automatiquement, pour synchroniser l'esclave et le maître. Notez que même avec cette stratégie, l'esclave aura des données obsolètes entre le moment où le maître s'éteint et celui où il est redémarré. Mais si vous utilisez l'option --init-file pour remplir la table MEMORY au lancement du serveur, elle s'assurera que cette intervalle est bien null.
La mémoire nécessaire pour les tables HEAP sont :
ALIGN() représente un facteur d'arrondi, car la taille de la ligne doit faire exactement un multiple de la taille du pointeur de char. sizeof(char*) vaut 4 sur les machines 32 bits et 8 sur une machine 64 bits.
Chaque table MEMORY est associée à un fichier sur le disque. Le fichier a le nom de la table, et pour extension .frm pour indiquer la définition de la table. Pour spécifier explicitement que vous voulez une table MEMORY, indiquez l'option ENGINE ou TYPE :
CREATE TABLE t (i INT) ENGINE = MEMORY; CREATE TABLE t (i INT) TYPE = HEAP;
mysql> CREATE TABLE test TYPE=MEMORY -> SELECT ip,SUM(downloads) AS down -> FROM log_table GROUP BY ip; mysql> SELECT COUNT(ip),AVG(down) FROM test; mysql> DROP TABLE test;
Les données pour les tables HEAP sont alloués par petits blocs. Les tables sont 100% dynamiques (en insertion). Aucune zone de débordement ou d'espace de clé supplémentaire n'est nécessaire. Les lignes effacées sont placées dans une liste, prêtes à être réutilisées.
Les tables MEMORY peuvent avoir jusqu'à 32 index par table, 16 colonnes par index, et un maximum de 500 pour la tailles des clés.
Avant MySQL 4.1, le moteur MEMORY n'implémentait que des index hash. Depuis MySQL 4.1, Les index hash sont le type par défaut, mais vous pouvez spécifier explicitement que l'index MEMORY doit être de type HASH ou BTREE en ajoutant la clause USING :
CREATE TABLE lookup (id INT, INDEX USING HASH (id)) ENGINE = MEMORY; CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
Vous pouvez avoir des clés non-uniques dans une table MEMORY. (C'est une fonctionnalité rare pour les index hash).
Si vous avez un index hash sur une table HEAP avec un haut degré de duplication (de nombreux valeurs d'index contiennent la même valeur), les modifications dans cette table peuvent affecter les valeurs des clés et toutes les suppressions seront plus lentes. Le facteur de ralentissement est proportionnel au degré de duplication (ou inversement proportionnel à la cardinalité). Depuis la version 4.1, MySQL supporte les index BTREE les tables HEAP, que vous pouvez utiliser pour éviter le problème.
Les tables HEAP utilisent un format de ligne fixe.
HEAP ne supporte pas les colonnes de type BLOB/TEXT.
HEAP ne supporte pas les colonnes de type AUTO_INCREMENT.
Avant MySQL 4.0.2, HEAP ne supportait les index sur les valeurs NULL.
Les tables HEAP sont partagées entre tous les clients (comme une autre table).
La caractéristique des tables MEMORY qui fait que les tables sont stockées en mémoire est partagée avec les tables internes que le serveur crée à la volée lors du traitement des requêtes. Cependant, les tables internes ont aussi la capacité d'être converties en tables disques automatiquement, si elles deviennent trop grandes. La taille limite est déterminée par la valeur de tmp_table_size. Les tables MEMORY ne peuvent pas être converties en tables disques. Pour vous assurer que vous ne faîtes rien de dangereux pour le serveur, vous pouvez utiliser la variable système max_heap_table_size pour imposer une taille maximale aux tables MEMORY. Pour des tables individuelles, vous pouvez utiliser l'option de table MAX_ROWS avec la commande CREATE TABLE.
Vous avez besoin de suffisamment de mémoire pour accepter toutes les tables HEAP que vous allez utiliser simultanément.
Pour libérer de la mémoire, vous devez exécuter la commande DELETE FROM heap_table, TRUNCATE heap_table ou DROP TABLE heap_table.
Si vous voulez remplir les tables MEMORY au lancement du serveur MySQL, vous pouvez utiliser l'option --init-file. Par exemple, vous pouvez mettre les commandes telles que INSERT INTO ... SELECT et LOAD DATA INFILE pour lire des données dans une source de données persistante. See Section 5.2.1, « Options de ligne de commande de mysqld ».
Si vous utilisez la réplication, les tables MEMORY du maître se vident à l'extinction. Rependant, un esclave peut ne pas s'apercevoir que ces tables ont été vidées, et il risque de retourner des données invalides si vous l'utilisez. Depuis MySQL 4.0.18, lorsqu'une table MEMORY est utilisée sur le maître, il émet une commande DELETE FROM automatiquement, pour synchroniser l'esclave et le maître. Notez que même avec cette stratégie, l'esclave aura des données obsolètes entre le moment où le maître s'éteint et celui où il est redémarré. Mais si vous utilisez l'option --init-file pour remplir la table MEMORY au lancement du serveur, elle s'assurera que cette intervalle est bien null.
La mémoire nécessaire pour les tables HEAP sont :
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) + ALIGN(length_of_row+1, sizeof(char*))