我有一个庞大的MySQL(InnoDB)数据库,会话表中有数百万行数据是由与我们运行在同一台服务器上、不相关且故障的网络爬虫创建的。不幸的是,现在我必须来解决这个问题。
如果我尝试执行 truncate table sessions;
看起来需要很长时间(超过30分钟)。我不关心数据;我只想尽可能快地清空该表。是否有更快的方法,或者我必须通宵等待呢?
(因为这篇内容在谷歌搜索结果中排名很高,所以我想提供更详细的说明。)
MySQL有一种便捷的方法可以像现有表格一样创建空表格,还有一个原子表重命名命令。结合起来,这是一种快速清除数据的方法:
CREATE TABLE new_foo LIKE foo;
RENAME TABLE foo TO old_foo, new_foo TO foo;
DROP TABLE old_foo;
完成
最快的方法是使用DROP TABLE完全删除表并使用相同的定义重新创建表。如果您的表上没有外键约束,则应该这样做。
如果您使用的MySQL版本大于5.0.3,则TRUNCATE将自动发生。您可能会从手册中获得一些有用的信息,它描述了带有FK约束的TRUNCATE的工作方式。http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html
编辑:TRUNCATE不同于drop或DELETE FROM。 对于那些对差异感到困惑的人,请检查上面的手册链接。 如果可以(如果没有FK),则TRUNCATE将像drop一样工作,否则它将像没有where子句的DELETE FROM一样运行。
编辑:如果您有一个大表,您的MariaDB / MySQL正在以ROW格式运行binlog_format,并且您执行没有谓词/ WHERE子句的DELETE,则在保持复制或甚至使Galera节点保持运行而不触发流控状态方面,您将遇到问题。此外,二进制日志可能会让您的磁盘充满。小心谨慎。
我发现在MySQL中最好的方法是:
DELETE from table_name LIMIT 1000;
或者是10,000(这取决于速度有多快)。
将它放在一个循环中,直到所有行都被删除。
请一定要尝试一下,因为它确实可行。虽然需要些时间,但它会起作用的。
drop table
应该是最快的摆脱它的方法。
你尝试过使用“drop”吗?我在超过20GB的表上使用它,总是在几秒钟内完成。
如果你只是想完全摆脱这个表格,为什么不直接删除它呢?
截断是非常快的,通常只需要几秒钟。如果它花费了30分钟,你可能遇到了一些外键引用了你要截断的表。这可能涉及到锁定问题。
截断实际上是清空表的最高效方法,但是你可能需要删除外键引用,除非你也想将这些表清空。
我们曾经遇到过这些问题。在Rails 2.x中,我们不再使用数据库作为会话存储器,而是使用cookie存储器。然而,删除表是一个不错的解决方案。您可能需要考虑停止mysql服务,暂时禁用日志记录,以安全模式启动并进行删除/创建操作。完成后,再次打开日志记录。
我不确定为什么这需要这么长时间。但是也许可以尝试重命名并重新创建一个空表。然后您可以放心地删除“额外”的表,而不必担心需要多长时间。
errno: 150 - 外键约束格式不正确
。 - brandones