Poiché tutte le tabelle sono MyISAM, ciò rende la mia risposta più facile da esprimere.
Innanzitutto, è necessario eseguire una query di INFORMATION_SCHEMA per le tabelle che hanno zero righe:
SELECT table_schema,table_name FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');
Quindi, formulare la query per eliminare le tabelle vuote:
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');
Ora, scarica i comandi in un file di testo SQL esterno.
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
Guarda i contenuti con uno dei seguenti
less DropTables.sql
cat DropTables.sql
Se sei soddisfatto del suo contenuto, esegui lo script:
mysql -uroot -p < DropTables.sql
o accedi a mysql ed eseguilo in questo modo:
mysql> source DropTables.sql
Provaci !!!
CAVEAT : questa tecnica funziona solo con la tabella MyISAM perché il conteggio delle righe di una tabella MyISAM è archiviato fisicamente nelle .MYD
tabelle. La tabella dei metadati INFORMATION_SCHEMA.TABLES legge sempre questo e si aggiorna. NON PROVARE QUESTO CON INNODB !!!
AGGIORNAMENTO 2014-02-05 11:46 EST
C'è un motivo che ho escluso ('information_schema','mysql','performance_schema')
Lo mysql
schema contiene tabelle vuote al suo interno. Alcuni MyISAM
, alcuni InnoDB
, alcuni CSV
.
Ad esempio, ecco le mie tabelle nello schema mysql per MySQL 5.6.15 sul mio desktop
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>
Se alcuni di questi tavoli erano a scomparire (come columns_priv
, proc_priv
, tables_priv
, etc.), il meccanismo di concessione potrebbe non funzionare correttamente o può causare mysqld non avviare. Inoltre, non vuoi colpire mysql.proc poiché è la sede fisica delle Stored Procedure. Altri meccanismi potrebbero non funzionare o se si desidera utilizzarli, come CrashSafe Replication utilizzando le tabelle InnoDB all'interno dello schema mysql o se si desidera inserire informazioni sul fuso orario.
AGGIORNAMENTO 2014-02-05 12:36 EST
Vorrei elogiare Tom Desp per la sua risposta per un motivo specifico: la sua sintassi potrebbe far cadere senza usare uno script esterno . Usando la sua idea, fammi acquisire il comando DROP TABLE in una variabile definita dall'utente.
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;
Se l'output di SELECT @DropCommand;
è corretto, quindi eseguire il comando in questo modo:
PREPARE s FROM @DropCommand;
EXECUTE s;
DEALLOCATE PREPARE s;
Questo elimina due cose:
- la necessità di un file di testo SQL esterno
- eseguendo un comando DROP TABLE separato per ogni tabella