เนื่องจากตารางทั้งหมดเป็น 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
ให้มันลอง !!!
ถ้ำ : เทคนิคนี้ใช้ได้กับตาราง MyISAM เท่านั้นเนื่องจากจำนวนแถวของตาราง MyISAM จะถูกเก็บไว้ใน.MYD
ตาราง ตารางข้อมูลเมตา Information_SCHEMA.TABLES จะอ่านและอัปเดตอยู่เสมอ อย่าลองสิ่งนี้กับ INNODB !!!
อัพเดท 2014-02-05 11:46 EST
มีเหตุผลที่ฉันยกเว้น ('information_schema','mysql','performance_schema')
mysql
สคีมีโต๊ะว่างในนั้น บางคนMyISAM
บางบางInnoDB
CSV
ตัวอย่างเช่นนี่คือตารางของฉันใน schema mysql สำหรับ MySQL 5.6.15 บนเดสก์ท็อปของฉัน
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 เพราะมันเป็นบ้านทางกายภาพของกระบวนงานที่เก็บไว้ กลไกอื่น ๆ อาจไม่ทำงานหากคุณต้องการใช้เช่น CrashSafe Replication โดยใช้ตาราง InnoDB ภายใน mysql schema หรือถ้าคุณต้องการแทรกข้อมูลเขตเวลา
อัปเดต 2014-02-05 12:36 EST
ผมอยากจะยกย่องทอม 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;
หากเอาต์พุตของ the SELECT @DropCommand;
นั้นถูกต้องให้รันคำสั่งดังนี้:
PREPARE s FROM @DropCommand;
EXECUTE s;
DEALLOCATE PREPARE s;
สิ่งนี้จะกำจัดสองสิ่ง:
- ความต้องการไฟล์ข้อความ SQL ภายนอก
- การรันคำสั่ง DROP TABLE แยกกันสำหรับแต่ละตาราง