Dans ce cas particulier, je pense que INFORMATION_SCHEMA
c'est un hareng rouge. D'après mes propres tests de SHOW COLUMNS
performances, la innodb_stats_on_metadata
variable 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 COLUMNS
et Les DESCRIBE
utilisent BLOB
comme 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 0
devrait 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_FIELD
structure sous-jacente pour extraire les types de données et les indicateurs, mais cela fonctionne environ 7 fois plus rapidement sur mon système.