Étant donné que toutes les tables sont MyISAM, cela rend ma réponse plus facile à exprimer.
Tout d'abord, vous devez interroger INFORMATION_SCHEMA pour les tables qui n'ont aucune ligne:
SELECT table_schema,table_name FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');
Ensuite, formulez la requête pour supprimer les tables vides:
SELECT CONCAT('DROP TABLE ',table_schema,'.',table_name,';') DropTableCommand
FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');
Maintenant, sauvegardez les commandes dans un fichier texte SQL externe.
SQL="SELECT CONCAT('DROP TABLE ',table_schema,'.',table_name,';') DropTableCommand"
SQL="${SQL} FROM information_schema.tables WHERE table_rows = 0 AND table_schema"
SQL="${SQL} NOT IN ('information_schema','mysql','performance_schema')"
mysql -uroot -p -ANe"${SQL}" > DropTables.sql
Regardez le contenu avec l'un des éléments suivants
less DropTables.sql
cat DropTables.sql
Si vous êtes satisfait de son contenu, exécutez le script:
mysql -uroot -p < DropTables.sql
ou connectez-vous à mysql et exécutez-le comme ceci:
mysql> source DropTables.sql
Essaie !!!
CAVEAT : cette technique ne fonctionne qu'avec la table MyISAM car le nombre de lignes d'une table MyISAM est physiquement stocké dans .MYD
les tables. La table de métadonnées INFORMATION_SCHEMA.TABLES est toujours en train de lire et de mettre à jour. N'ESSAYEZ PAS CELA AVEC INNODB !!!
MISE À JOUR 2014-02-05 11:46 EST
Il y a une raison pour laquelle j'ai exclu ('information_schema','mysql','performance_schema')
Le mysql
schéma contient des tables vides. Certains MyISAM
, certains InnoDB
, certains CSV
.
Par exemple, voici mes tables dans le schéma mysql pour MySQL 5.6.15 sur mon bureau
mysql> select table_name,engine,table_rows
-> from information_schema.tables
-> where table_schema='mysql';
+---------------------------+--------+------------+
| table_name | engine | table_rows |
+---------------------------+--------+------------+
| columns_priv | MyISAM | 0 |
| db | MyISAM | 2 |
| event | MyISAM | 0 |
| func | MyISAM | 0 |
| general_log | CSV | 2 |
| help_category | MyISAM | 40 |
| help_keyword | MyISAM | 485 |
| help_relation | MyISAM | 1090 |
| help_topic | MyISAM | 534 |
| innodb_index_stats | InnoDB | 0 |
| innodb_table_stats | InnoDB | 0 |
| ndb_binlog_index | MyISAM | 0 |
| plugin | MyISAM | 0 |
| proc | MyISAM | 0 |
| procs_priv | MyISAM | 0 |
| proxies_priv | MyISAM | 1 |
| servers | MyISAM | 0 |
| slave_master_info | InnoDB | 0 |
| slave_relay_log_info | InnoDB | 0 |
| slave_worker_info | InnoDB | 0 |
| slow_log | CSV | 2 |
| tables_priv | MyISAM | 0 |
| time_zone | MyISAM | 0 |
| time_zone_leap_second | MyISAM | 0 |
| time_zone_name | MyISAM | 0 |
| time_zone_transition | MyISAM | 0 |
| time_zone_transition_type | MyISAM | 0 |
| user | MyISAM | 6 |
+---------------------------+--------+------------+
28 rows in set (0.01 sec)
mysql>
Si certains de ces tableaux devaient disparaître (comme columns_priv
, proc_priv
, tables_priv
, etc.), le mécanisme de subvention peut ne pas fonctionner correctement ou peut causer mysqld de ne pas démarrer. Vous ne voulez pas non plus casser le fichier mysql.proc car il s'agit de la base physique des procédures stockées. D'autres mécanismes peuvent ne pas fonctionner si vous souhaitez les utiliser, comme la réplication CrashSafe en utilisant les tables InnoDB à l'intérieur du schéma mysql, ou si vous souhaitez insérer des informations de fuseau horaire.
MISE À JOUR 2014-02-05 12:36 EST
Je tiens à féliciter Tom Desp pour sa réponse pour une raison spécifique: sa syntaxe pourrait faire le drop sans utiliser de script externe . En utilisant son idée, permettez-moi de capturer la commande DROP TABLE dans une variable définie par l'utilisateur.
SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(DBTB),';')
INTO @DropCommand
FROM (SELECT CONCAT(table_schema,'.',table_name) DBTB
FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema')) A;
SELECT @DropCommand;
Si la sortie du SELECT @DropCommand;
est correcte, exécutez la commande comme ceci:
PREPARE s FROM @DropCommand;
EXECUTE s;
DEALLOCATE PREPARE s;
Cela élimine deux choses:
- la nécessité d'un fichier texte SQL externe
- exécuter une commande DROP TABLE distincte pour chaque table