Configuration du serveur
Introduction
Configurer correctement MariaDB est essentiel pour assurer à la fois la performance et la stabilité du serveur. Plusieurs centaines d’options sont disponibles, ce qui rend difficile le choix des paramètres. Par ailleurs, dans de nombreux cas, il n’existe pas une seule bonne valeur que vous pouvez appliquer les yeux fermés : bien souvent, plusieurs valeurs sont acceptables pour une option et la meilleure configuration va dépendre de votre utilisation du serveur.
Cependant, obtenir une configuration saine de son serveur MariaDB n’est finalement pas si compliqué. Tout d’abord, sachez qu’il n’existe pas de configuration idéale : si vos requêtes s’exécutent sans lenteur particulière et que le serveur ne montre jamais de signes de surcharge, cela signifie que les paramètres essentiels sont correctement ajustés. Ensuite, sachez que tous les problèmes de performances ne se résolvent pas seulement en modifiant la configuration : d’autres facteurs comme les ressources matérielles, le schéma des tables et les index ont également un impact majeur sur les performances. Enfin, gardez à l’esprit que, mis à part une vingtaine de paramètres qu’il est absolument essentiel de connaître et de savoir ajuster, la plupart des options n’ont d’intérêt...
Comment configurer le serveur ?
Les options peuvent être définies à différents niveaux :
-
Lors de la compilation des sources en exécutant le script configure.
-
Dans le fichier de configuration my.cnf (my.ini sous Microsoft Windows).
-
En tant que paramètres du programme mysqld.
-
Dynamiquement, c’est-à-dire durant l’exécution du serveur (à chaud), à l’aide de la commande SET.
Si une option est redéfinie sur plusieurs niveaux, c’est sa valeur sur le niveau le plus bas de cette liste qui sera prise en compte. Par exemple, si dans votre fichier de configuration l’option long-query-time vaut 10 et qu’elle vaut 2 en la passant à l’exécutable mysqld, sa valeur pour le serveur sera donc 2.
La méthode la plus pratique, la plus sûre et qui est donc recommandée pour paramétrer le serveur est d’utiliser le fichier de configuration. Cependant la modification dynamique des options s’impose parfois.
1. Paramétrage lors de la compilation
Une des manières d’installer le serveur MariaDB consiste à compiler ses sources. Sous Linux, lors du lancement du script configure, il est alors possible de personnaliser votre installation en lui passant les options adéquates. Cette solution est souvent utilisée dans les grands comptes pour faire correspondre l’installation du serveur à la norme en vigueur dans l’entreprise ou encore pour des raisons de performance. Les directives ainsi spécifiées constitueront le paramétrage par défaut, sauf si les valeurs sont changées à l’un des autres niveaux de configuration.
La compilation de MariaDB sur les différentes plates-formes est détaillée dans la documentation en ligne : https://mariadb.com/kb/en/mariadb/compiling-mariadb-from-source/
2. Paramétrage dans le fichier de configuration
a. Localisation du fichier de configuration
Le fichier my.cnf (ou my.ini sous MS Windows) est le fichier de configuration du serveur MariaDB. Les programmes fournis par MariaDB (mysqld, mysql, mysqldump, myisamchk...) viennent y chercher leurs directives. Sous UNIX, ils recherchent automatiquement le fichier my.cnf dans les répertoires suivants : /etc/, /etc/mysql/, SYSCONFDIR/, $MYSQL_HOME/ et ~/. SYSCONFDIR étant le répertoire spécifié...
Visualisation de la configuration
L’administrateur a plusieurs possibilités pour visualiser la configuration du serveur MariaDB. La manière la plus évidente est de passer par le fichier de configuration. Toutefois, il est possible que certaines des options qu’il contient soient redéfinies en étant passées en paramètre de mysqld. Il faut alors aussi penser à regarder l’état du processus mysqld, par exemple avec la commande ps -ef | grep mysqld sous Linux.
Mais ces deux premières méthodes ont quelques limites. Sur un serveur mal administré, vous pouvez trouver plusieurs fichiers de configuration qui ne sont pas forcément tous utilisés par le serveur et il n’y a aucune obligation qu’ils se nomment my.cnf (ou my.ini). De plus, dans le fichier de configuration, tous les paramètres ne s’y trouvent généralement pas et ceux qui y sont peuvent, comme pour ceux passés en paramètre de mysqld, être redéfinis à chaud.
Pour être certain de visualiser la configuration actuelle du serveur, vous devez donc utiliser soit la commande SHOW GLOBAL VARIABLES, soit les tables GLOBAL_VARIABLES du schéma virtuel INFORMATION_SCHEMA ou la commande SELECT @@global.nom_variable.
mysql> SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE
VARIABLE_NAME = 'datadir';
+---------------+-----------------------+ ...
Configuration d’InnoDB
1. Paramètres essentiels
Les paramètres évoqués dans cette section ne sont pas nécessairement à modifier par rapport à la configuration par défaut, mais il est important que vous ayez réfléchi à leur bonne valeur pour votre application.
-
Taille du cache mémoire (innodb_buffer_pool_size) : il s’agit du cache principal d’InnoDB (buffer pool), où données et index fréquemment accédés sont stockés. Pour un serveur dédié à MariaDB, il est courant de lui allouer la majeure partie de la mémoire du serveur (par exemple, environ 25 Go pour un serveur ayant 32 Go de mémoire physique). L’idée principale est que ce cache permet d’éviter les accès au disque : la taille du cache est d’autant plus importante que le disque est lent.
Si votre base de données est petite (quelques dizaines de Go, par exemple), il est assez simple d’utiliser un serveur ayant suffisamment de mémoire pour que l’ensemble des données et index InnoDB tiennent dans le cache. Sinon, il faut essayer de faire tenir en cache la partie utile des données et index, c’est-à-dire la partie des données et index qui est fréquemment utilisée par l’application. Il est assez fréquent en effet d’avoir par exemple une base de 500 Go contenant l’historique des données sur les cinq dernières années, mais pour laquelle seules les données du dernier mois sont régulièrement consultées, ce qui va représenter 10 Go. Dans ce cas, il est inutile de chercher à allouer 500 Go au buffer pool, 10-15 Go seront suffisants.
-
Taille du journal transactionnel (innodb_log_file_size) : le journal transactionnel (redo log) permet à InnoDB d’offrir de bonnes performances en écriture tout en garantissant l’intégrité des données en cas d’arrêt inopiné (voir chapitre Généralités sur MariaDB). Pour rappel, l’idée principale est qu’InnoDB écrit de manière synchrone les modifications dans son journal transactionnel (écritures peu coûteuses puisque séquentielles) et qu’un...
La journalisation
Le serveur MariaDB utilise quatre types de journaux, qui ont chacun leurs spécialisations : le journal binaire (binary log ou encore binlog), le journal des requêtes lentes (slow query log), le journal général (general query log) et le journal des erreurs (error log), le seul des quatre à être activé par défaut.
Le relay-log, un autre type de journal, est créé par le serveur lors de la réplication. Il est abordé au chapitre Réplication.
1. Le journal binaire
Le journal binaire ou binlog est chargé de stocker, sous un format binaire, toutes les requêtes qui modifient les objets de la base de données (INSERT, UPDATE, DELETE, DROP, CREATE, ALTER...). C’est l’élément central de la réplication MariaDB (voir chapitre Réplication). Il est également très utile à la restauration des données (voir chapitre Sauvegarde et restauration). Pour activer la journalisation binaire, utilisez l’option log-bin, et pour définir son fichier d’index, il faut paramétrer l’option log-bin-index. Ce fichier, qui contient la liste de tous les journaux binaires depuis la dernière purge, permet au serveur de connaître le nom du fichier courant, qui est obtenu avec la commande SHOW MASTER STATUS, mais aussi d’afficher la liste de tous les journaux binaires présents sur le serveur avec SHOW BINARY LOGS. La journalisation binaire peut être désactivée à chaud, mais seulement pour la session d’un client, avec l’option SQL_LOG_BIN.
Ne confondez pas les journaux binaires, qui enregistrent toutes les écritures, avec les journaux transactionnels d’InnoDB (redo logs), qui n’enregistrent que les écritures sur les tables InnoDB et dont le seul but est d’assurer la restauration automatique d’InnoDB en cas d’arrêt inopiné.
Une configuration de base pourrait être :
[mysqld]
log-bin = /var/lib/mysql/mysql-bin
Notez que log-bin-index n’ayant pas été défini, par défaut le fichier sera créé dans le même répertoire que les journaux binaires (/var/lib/mysql ici).
Notez également que vous pouvez indiquer un chemin relatif pour l’option log-bin. Dans ce cas...
Le mode SQL
Le comportement par défaut du serveur MariaDB est assez permissif, notamment en ce qui concerne la cohérence des données. Le postulat est en quelque sorte : « Les données reçues sont cohérentes, les vérifier est donc superflu », ce qui dans la réalité n’est pas toujours le cas. Si votre application vérifie toutes les données, cela a un sens de dispenser le serveur de ces vérifications qui peuvent être coûteuses pour les performances. Dans le cas contraire ou si les données peuvent être atteintes par d’autres biais que l’application, vous devrez faire les vérifications au niveau du serveur. Par exemple, si une chaîne de caractères est trop longue pour être insérée dans une colonne, le serveur exécutera quand même l’insertion en tronquant la chaîne de caractères et en renvoyant un avertissement (warning) au client lui disant que les données ont été tronquées pour que l’insertion réussisse. Cela pose deux problèmes majeurs pour la plupart des applications. Premièrement la donnée stockée dans la table n’est pas celle envoyée par le client, la cohérence des données n’est donc pas assurée. Deuxièmement, notre expérience nous a montré que très peu de développeurs traitent les avertissements renvoyés par le serveur, ce qui veut finalement dire qu’une donnée non conforme est insérée en base et que personne n’est au courant. L’option sql_mode permet de régler ce genre de problème. Cette option peut changer le comportement du serveur :
-
En renforçant la cohérence en empêchant l’insertion implicite de données invalides.
-
En rendant le code SQL portable.
-
En assurant un comportement du serveur proche de celui d’autres SGBD.
1. Les modes usuels
Avec MariaDB 10.1, la valeur par défaut de la variable sql_mode est NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION (le comportement de ce mode est expliqué un peu plus bas).
À titre de comparaison, le mode SQL par défaut de MySQL 5.7 est ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION.
mysql> SHOW SESSION VARIABLES LIKE 'sql_mode';
+---------------+--------------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------------+
| sql_mode | NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
Prenons maintenant un exemple pour illustrer le rôle du mode SQL.
La table char3tinyint contient deux colonnes : c en CHAR(3), chaîne contenant trois caractères maximum, et i en TINYINT, qui n’accepte que les nombres entiers de -128 à 127.
mysql> SHOW CREATE TABLE char3tinyint \G
*************************** 1. row ***************************
Table: char3tinyint
Create Table: CREATE TABLE `char3tinyint` (
`c` char(3) DEFAULT NULL,
`i` tinyint(4) DEFAULT NULL
);
mysql> INSERT INTO char3tinyint VALUES('abc',127);
Query OK, 1 row affected (0,00 sec)
mysql> SELECT * FROM char3tinyint;
+------+------+
| c | i |
+------+------+
| abc | 127 |
+------+------+
La chaîne de caractères LeMUG est trop longue pour être stockée entièrement dans une colonne de type CHAR(3), le mode SQL par défaut étant permissif, le serveur va stocker ce qu’il peut, c’est-à-dire les trois premiers caractères et ignorer les deux suivants. Il tronque donc la chaîne de caractères. Dans la deuxième colonne, l’entier 2008 dépasse la borne maximale du type TINYINT qui vaut 127. Étant au-dessus de cette borne, c’est la valeur maximale, c’est-à-dire 127, qui va être stockée (si le nombre était inférieur à -128, c’est ce dernier nombre qui aurait été stocké). Pour chacune de ces colonnes, le serveur renvoie un avertissement qui décrit l’opération qu’il a implicitement réalisée.
mysql> INSERT INTO char3tinyint VALUES('LeMUG',2008);
Query OK, 1 row affected, 2 warnings (0,00 sec)
mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1265 | Data truncated for column 'c' at row 1 |
| Warning | 1264 | Out of range value for column 'i' at row 1 |
+---------+------+--------------------------------------------+
mysql> SELECT * FROM char3tinyint;
+------+------+
| c | i |
+------+------+
| abc | 127 |
| LeM | 127 |
+------+------+
Le mode SQL devient strict pour la session grâce à la valeur STRICT_ALL_TABLES. Les données invalides sont rejetées, et une erreur est renvoyée car l’insertion ne se fait pas.
mysql> SET SESSION
sql_mode=CONCAT(@@sql_mode,',','STRICT_ALL_TABLES');
Query OK, 0 rows affected (0,00 sec)
mysql [localhost] {msandbox} (test) > SHOW SESSION VARIABLES LIKE
'sql_mode';
+---------------+------------------------------------------+
| Variable_name | Value |
+---------------+------------------------------------------+
| sql_mode | STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION |
+---------------+------------------------------------------+
1 row in set (0,00 sec)
mysql> INSERT char3tinyint VALUES('LeMUG',2008);
ERROR 1406 (22001): Data too long for column 'c' at row 1
mysql> SELECT * FROM char3tinyint;
+------+------+
| c | i |
+------+------+
| abc | 127 |
| LeM | 127 |
+------+------+
Parmi les variables qui permettent de renforcer la cohérence des données, on trouve aussi :
-
NO_ENGINE_SUBSTITUTION : lors d’une commande CREATE TABLE ou ALTER TABLE, si le moteur de stockage demandé lors de la création ou de la modification d’une table n’existe pas, le serveur renvoie une erreur et n’exécute donc pas la commande. Dans le cas contraire, un avertissement est renvoyé (warning) et la table est tout de même créée ou modifiée avec le moteur de stockage par défaut.
Dans l’exemple suivant, le moteur ARIA est inconnu sur ce serveur. En supprimant le mode SQL NO_ENGINE_SUBSTITUTION, le serveur crée donc la table avec le moteur par défaut, InnoDB.
mysql> SET SESSION sql_mode='';
mysql> SHOW SESSION VARIABLES LIKE 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode | |
+---------------+-------+
mysql> CREATE TABLE t_ARIA(i int)ENGINE = ARIA;
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------+
| Warning | 1286 | Unknown table engine 'ARIA' |
| Warning | 1266 | Using storage engine InnoDB for table 't_ARIA'|
+---------+------+-----------------------------------------------+
mysql> SHOW CREATE TABLE t_ARIA \G
*************************** 1. row ***************************
Table: t_ARIA
Create Table: CREATE TABLE `t_ARIA` (
`i` int(11) DEFAULT NULL
) ENGINE=InnoDB;
mysql> SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION';
mysql> CREATE TABLE t_ARIA2(i int)ENGINE = ARIA;
-
STRICT_ALL_TABLES et STRICT_TRANS_TABLES : si le mode SQL contient l’un de ces deux paramètres, le mode est dit strict. Les données invalides sont rejetées et une erreur est renvoyée car la modification ne se fait pas. Avec l’une ou l’autre des options, le comportement du serveur est identique sur des tables qui utilisent un moteur de stockage transactionnel comme c’est le cas avec InnoDB. Sur des tables qui ont un moteur non transactionnel (MyISAM par exemple), leur comportement diffère lors d’insertions multiples, c’est-à-dire en cas d’insertion de plusieurs enregistrements dans une seule requête INSERT.
Avec le mode STRICT_ALL_TABLES, le serveur renvoie une erreur à la première donnée invalide. Le moteur n’étant pas transactionnel, les données déjà insérées restent, ce qui peut entraîner des problèmes de cohérences. La solution pour ne pas se retrouver dans un tel cas est d’écrire vos requêtes INSERT avec seulement un enregistrement à la fois. Alors que, dans le même contexte, avec le mode STRICT_TRANS_TABLES, les données invalides sont insérées en étant converties en la valeur valide la plus proche. Le serveur génère néanmoins un avertissement.
À noter que si les deux modes sont activés, c’est le comportement du mode STRICT_ALL_TABLES qui prend le dessus.
mysql> SET SESSION sql_mode='STRICT_ALL_TABLES';
mysql> INSERT INTO t_myisam VALUES ('a',100),('ab',200);
ERROR 1264 (22003): Out of range value for column 'i' at row 2
mysql> SELECT * FROM t_myisam;
+------+------+
| c | i |
+------+------+
| a | 100 |
+------+------+
mysql> SET SESSION sql_mode='STRICT_TRANS_TABLES';
mysql> INSERT INTO t_myisam VALUES ('b',111),('ab',200);
Query OK, 2 rows affected, 1 warning (0,00 sec)
Records: 2 Duplicates: 0 Warnings: 1
mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'i' at row 2 |
+---------+------+--------------------------------------------+
mysql> SELECT * FROM t_myisam;
+----+-----+
| c | i |
+----+-----+
| a | 100 |
| b | 111 |
| ab | 127 |
+----+-----+
mysql> SET SESSION sql_mode='STRICT_TRANS_TABLES,
STRICT_ALL_TABLES';
mysql> INSERT INTO t_myisam VALUES ('abc',1),('abcdef',50);
ERROR 1406 (22001): Data too long for column 'c' at row 2
mysql> SELECT * FROM t_myisam;
+------+------+
| c | i |
+------+------+
| a | 100 |
| b | 111 |
| ab | 127 |
| abc | 1 |
+------+------+
4 row in set (0,00 sec)
-
ERROR_FOR_DIVISION_BY_ZERO : renvoie un avertissement en cas de mise à jour d’un champ avec le résultat d’une division par zéro ou de modulo par 0.
mysql> SET SESSION sql_mode='ERROR_FOR_DIVISION_BY_ZERO';
mysql> INSERT ma_table VALUES (1/0);
Query OK, 1 row affected, 1 warning (0,00 sec)
mysql> SHOW WARNINGS;
+-------+------+---------------+
| Level | Code | Message |
+-------+------+---------------+
| Error | 1365 | Division by 0 |
+-------+------+---------------+
-
NO_ZERO_DATE : renvoie un avertissement si la date écrite dans la table est zéro (’0000-00-00’, ’0000/00/00’...). Combiné avec les modes STRICT_TRANS_TABLES ou STRICT_ALL_TABLES, la donnée modifiée (INSERT ou UPDATE) n’est pas mise à jour et une erreur est renvoyée.
mysql> SET SESSION sql_mode='NO_ZERO_DATE,STRICT_TRANS_TABLES';
mysql> INSERT INTO ma_table values('0000-00-00 00:00:00');
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00
00:00:00' for column 'd' at row 1
-
NO_ZERO_IN_DATE : renvoie un avertissement si l’année, le mois ou le jour sont à zéro. Combiné avec les modes STRICT_TRANS_TABLES ou STRICT_ALL_TABLES, la donnée modifiée (INSERT ou UPDATE) n’est pas mise à jour et une erreur est renvoyée. À noter que la valeur zéro (’0000-00-00’, ’0000/00/00’...) est acceptée.
mysql> SET SESSION sql_mode ='STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
mysql> INSERT INTO t1 VALUES ('0000-00-00');
Query OK, 1 row affected (0,00 sec)
mysql> INSERT INTO t1 VALUES ('0000-00-01');
ERROR 1292 (22007): Incorrect datetime value: '0000-00-01' for
column 'd' at row 1
mysql> INSERT INTO t1 VALUES ('0000-01-00');
ERROR 1292 (22007): Incorrect datetime value: '0000-01-00' for
column 'd' at row 1
mysql> INSERT INTO t1 VALUES ('0001-00-00');
ERROR 1292 (22007): Incorrect datetime value: '0001-00-00' for
column 'd' at row 1
mysql> INSERT INTO t1 VALUES ('1974-11-12');
Query OK, 1 row affected (0,00 sec)
-
NO_AUTO_CREATE_USER : interdit la création de comptes utilisateurs sans mots de passe avec la commande GRANT. Il est cependant possible de créer un utilisateur sans mot de passe, avec la commande CREATE USER.
mysql> GRANT USAGE ON *.* TO 'IT';
ERROR 1133 (42000): Can't find any matching row in the user table
mysql> GRANT USAGE ON *.* TO 'IT' IDENTIFIED BY 'mot2pass3';
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE USER 'viadeo';
Query OK, 0 rows affected (0,00 sec)
INSERT IGNORE / UPDATE IGNORE : les requêtes INSERT IGNORE et UPDATE IGNORE permettent de contourner les modes SQL qui renforcent la cohérence des données, dont le mode strict. La modification des données sera donc possible, cependant le serveur renverra un avertissement. En d’autres termes, avec la clause IGNORE le fonctionnement du serveur est similaire à mode_sql=’’.
2. Les combinaisons de modes
Vous pouvez combiner plusieurs modes SQL, il suffit de les mettre à la suite, séparés par une virgule et sans espaces, le tout en une seule commande. Cette manipulation peut se faire à chaud, pour la session ou de manière globale. Cependant comme pour les autres options, il est préférable de la définir dans le fichier de configuration.
[mysqld]
sql_mode=STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,
NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
L’option sql_mode peut aussi prendre comme valeur des combinaisons de modes prédéfinis. Pour avoir un comportement strict du serveur, utilisez le mode SQL TRADITIONAL. Il est équivalent aux modes ’STRICT_ TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_ DATE, ERROR_FOR_DIVISION_BY_ZERO...
Autres paramètres à configurer
1. Paramètres MyISAM
Le seul réel paramètre important pour les tables MyISAM est la taille du cache d’index, commandée par la variable key_buffer_size.
Pour vous aider à trouver une bonne taille, vous allez regarder les valeurs de trois variables de statut parmi le résultat de la commande :
mysql> SHOW GLOBAL STATUS LIKE 'Key_%';
Les deux premières variables à considérer sont Key_reads et Key_read_requests. Key_reads indique le nombre de requêtes de lectures d’index qui n’ont pas pu être satisfaites par le cache et Key_read_requests indique le nombre de lectures faites dans l’index. Si vous calculez le taux d’utilisation du cache par la formule (1 - Key_reads / Key_read_requests) x 100, votre cache devrait être bien paramétré si votre taux est proche de 100 %. Si le taux est faible, votre cache est sans doute trop petit et vous pouvez augmenter la valeur de key_buffer_size.
La troisième variable à regarder est Key_blocks_unused, qui vous donne le nombre de blocs disponibles dans le cache. Si votre taux d’utilisation est faible et que le nombre de blocs disponibles est également faible, votre cache est très certainement trop petit.
Sachez qu’il n’est pas pénalisant de prévoir un cache surdimensionné, car la mémoire ne sera allouée qu’en cas de besoin, contrairement au cache de requêtes.
Il n’existe pas d’option pour mettre en cache les données des tables MyISAM. Seul le système d’exploitation met en cache les données, ce qui est cependant beaucoup moins efficace qu’un cache spécialisé comme celui existant pour les index.
2. Cache de requêtes
a. Rôle du cache
MySQL maintient un ensemble de résultats de requêtes de type SELECT dans une structure en mémoire dédiée appelée cache de requêtes. Lorsqu’un SELECT est exécuté, le serveur stocke le résultat dans le cache de sorte que, si un client demande la même requête dans un temps suffisamment proche pour que les tables n’aient pas changé, le serveur puisse renvoyer directement le résultat qu’il a conservé en mémoire au lieu de passer par toutes...