Dans ce cas particulier, je pense que INFORMATION_SCHEMAc'est un hareng rouge. D'après mes propres tests de SHOW COLUMNSperformances, la innodb_stats_on_metadatavariable ne semble pas faire de différence sur les tables MyISAM ou InnoDB.
Cependant, à partir du manuel MySQL 5.0 ...
Certaines conditions empêchent l'utilisation d'une table temporaire en mémoire, auquel cas le serveur utilise à la place une table sur disque:
[...]
- Les instructions
SHOW COLUMNSet Les DESCRIBEutilisent BLOBcomme type pour certaines colonnes, donc la table temporaire utilisée pour les résultats est une table sur disque.
Cela semble avoir été supprimé du manuel à partir de MySQL 5.5, mais semble toujours s'appliquer dans cette version ...
mysql> SHOW VARIABLES LIKE 'version';
+---------------+-------------------------+
| Variable_name | Value |
+---------------+-------------------------+
| version | 5.5.41-0ubuntu0.14.04.1 |
+---------------+-------------------------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'Created_tmp_disk_tables';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0 |
+-------------------------+-------+
1 row in set (0.00 sec)
mysql> SHOW COLUMNS FROM mysql.user;
[...snip...]
42 rows in set (0.00 sec)
mysql> SHOW STATUS LIKE 'Created_tmp_disk_tables';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 1 |
+-------------------------+-------+
1 row in set (0.00 sec)
Les informations de champ renvoyées avec un jeu de résultats de requête contiennent les mêmes informations que celles renvoyées par SHOW COLUMNS, donc a SELECT * FROM my_table LIMIT 0devrait réaliser la même chose sans créer de table temporaire sur disque par requête.
Un exemple rapide pour simplement saisir les noms de champs en PHP ...
$mysql = new mysqli('localhost', 'root', '', 'my_database');
$field_names = array();
$result = $mysql->query("SELECT * FROM my_table LIMIT 0");
$fields = $result->fetch_fields();
foreach ($fields as $fields)
{
$field_names[] = $field->name;
}
var_dump($field_names);
La récupération des informations de champ de cette manière est un peu plus difficile à décoder. Vous devrez consulter la description de la MYSQL_FIELDstructure sous-jacente pour extraire les types de données et les indicateurs, mais cela fonctionne environ 7 fois plus rapidement sur mon système.