是否可以从庞大的数据库(mysql)中删除所有空表?
我正在寻找一个sql命令来自动删除所有这些空表。
当前,我的数据集中有305个表,其中约30%是旧的空表,这些表将不会在新应用程序中使用。
只是为了澄清;所有表的类型为= MyISAM
是否可以从庞大的数据库(mysql)中删除所有空表?
我正在寻找一个sql命令来自动删除所有这些空表。
当前,我的数据集中有305个表,其中约30%是旧的空表,这些表将不会在新应用程序中使用。
只是为了澄清;所有表的类型为= MyISAM
Answers:
这个想法可能是使用以下命令查找空表 INFORMATION_SCHEMA.TABLES
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_ROWS = '0'
AND TABLE_SCHEMA = 'my_database_only'
然后,您可以使用以下命令生成SQL查询
SELECT CONCAT('DROP TABLE ', GROUP_CONCAT(table_name), ';') AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_ROWS = '0'
AND TABLE_SCHEMA = 'my_database_only';
快速但有点脏,但实际上应该可以工作。
由于所有表都是MyISAM,这使我的答案更易于表达。
首先,您需要查询INFORMATION_SCHEMA以获取具有零行的表:
SELECT table_schema,table_name FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');
接下来,制定查询以删除空表:
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');
现在,将命令转储到外部SQL文本文件中。
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
用下列其中一项查看内容
less DropTables.sql
cat DropTables.sql
如果对其内容感到满意,请运行脚本:
mysql -uroot -p < DropTables.sql
或登录到mysql并像这样运行它:
mysql> source DropTables.sql
CAVEAT:此技术仅适用于MyISAM表,因为MyISAM表的行数实际存储在.MYD
表的中。INFORMATION_SCHEMA.TABLES元数据表始终在读取并更新。请勿尝试使用INNODB !!!
我被排除在外是有原因的 ('information_schema','mysql','performance_schema')
该mysql
模式中有空表。一些MyISAM
,一些InnoDB
,一些CSV
。
例如,这是我的台式机上MySQL 5.6.15的mysql模式中的表
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>
如果某些这些表都是消失(如columns_priv
,proc_priv
,tables_priv
,等),确认机制可能无法正常工作或可能造成的mysqld不启动。您也不想破坏mysql.proc,因为它是存储过程的物理位置。其他机制可能不起作用,或者是您想使用它们,例如使用mysql架构内的InnoDB表进行CrashSafe复制,或者要插入时区信息。
我要赞扬汤姆·德斯普(Tom Desp)的回答是有特定原因的:他的语法可以在不使用外部脚本的情况下进行删除。使用他的想法,让我将DROP TABLE命令捕获到用户定义的变量中。
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;
如果的输出SELECT @DropCommand;
正确,则执行以下命令:
PREPARE s FROM @DropCommand;
EXECUTE s;
DEALLOCATE PREPARE s;
这消除了两件事: