每周一次cronjob会从使用InnoDB引擎的MySQL表中删除大约500,000条记录。该表包含每周处理的Web日志数据,之后删除不再需要的数据。此表上有3个索引(无外键),包括时间,即unix时间戳。
DELETE FROM global_viewlog WHERE time< 1354391592
问题是上周运行的这个查询需要2个多小时才能运行,在此期间我的整个服务器都滞后了。 'iotop'透露了由MySQL引用的硬盘大量引用的硬盘,服务器负载急剧增加到不健康的水平。
每次点击都会写入表格。房间里有一只我没看见的大象吗?即,优化每周查询的一些明显的东西是什么?
由于
答案 0 :(得分:4)
如果您经常根据时间删除旧数据,则基于同一列对表进行分区将使速度更快。它会将不同的时间段分隔到磁盘上的不同区域,因此删除只会删除整个块而不是查看单个行。
答案 1 :(得分:2)
您正在使用InnoDB,因此存在隐式事务。你删除了一大堆记录,所以交易很大。 @Erik Ekman是对的,如果你可以分区工作,这是处理这个问题的好方法。
但这是另一个好方法。尝试以较小批量删除,如此。
DELETE
FROM global_viewlog
WHERE time<135439159
LIMIT 1000
继续发出此声明,直到删除任何内容为止。大多数客户端库(JDBC等)返回受影响的记录数。或者,如果您想以便宜的方式执行此操作,您可以从脚本中发出一千次语句。
(您可以使用LIMIT
语句中的记录数量。)它可能会或可能不会比单个删除语句花费更多的时间,但它不会占用您的服务器。< / p>
尝试将此表的访问方法更改为MyISAM并使用:
DELETE LOW_PRIORITY QUICK
FROM global_viewlog
WHERE time<135439159
这将使您的清理操作不会干扰生产。
将您的cronjob频率从每周一次更改为每天一次。这将减少删除批次的大小,因此您没有这么多的清理混乱。