Como todas as tabelas são MyISAM, isso facilita minha expressão.
Primeiro, você precisa consultar o INFORMATION_SCHEMA para as tabelas que possuem zero linhas:
SELECT table_schema,table_name FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');
Em seguida, formule a consulta para descartar as tabelas vazias:
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');
Agora, despeje os comandos em um arquivo de texto SQL externo.
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
Veja o conteúdo com um dos seguintes
less DropTables.sql
cat DropTables.sql
Se você estiver satisfeito com seu conteúdo, execute o script:
mysql -uroot -p < DropTables.sql
ou faça o login no mysql e execute-o assim:
mysql> source DropTables.sql
De uma chance !!!
CAVEAT : Esta técnica funciona apenas com a tabela MyISAM porque a contagem de linhas de uma tabela MyISAM é fisicamente armazenada nas .MYD
tabelas. A tabela de metadados INFORMATION_SCHEMA.TABLES está sempre lendo isso e atualizando. NÃO TENTE ISTO COM INNODB !!!
ATUALIZAÇÃO 05-02-2014 11:46 EST
Há uma razão pela qual eu excluí ('information_schema','mysql','performance_schema')
O mysql
esquema possui tabelas vazias. Alguns MyISAM
, alguns InnoDB
, alguns CSV
.
Por exemplo, aqui estão minhas tabelas no esquema mysql para MySQL 5.6.15 na minha área de trabalho
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 algumas dessas mesas estavam a desaparecer (como columns_priv
, proc_priv
, tables_priv
, etc.), o mecanismo de subvenção pode não funcionar corretamente ou pode causar mysqld não iniciar. Você também não quer bater o mysql.proc, pois é o lar físico dos Procedimentos Armazenados. Outros mecanismos podem não funcionar, caso você queira usá-los, como CrashSafe Replication, usando as tabelas InnoDB dentro do esquema mysql, ou se desejar inserir informações de fuso horário.
ATUALIZAÇÃO 05-02-2014 12:36 EST
Gostaria de felicitar Tom Desp por sua resposta por um motivo específico: sua sintaxe pode ser eliminada sem o uso de um script externo . Usando sua ideia, deixe-me capturar o comando DROP TABLE em uma variável definida pelo usuário.
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 a saída do SELECT @DropCommand;
estiver correta, execute o comando da seguinte maneira:
PREPARE s FROM @DropCommand;
EXECUTE s;
DEALLOCATE PREPARE s;
Isso elimina duas coisas:
- a necessidade de um arquivo de texto SQL externo
- executando um comando DROP TABLE separado para cada tabela