我在Centos 6.4 64位操作系统上使用mysql server v5.1.73。我有一个大约17m记录的表,它的大小约为10GB。这个表的mysql引擎是innodb
这个表有10列,其中一列是' date'其类型是日期时间。我想用mysql删除特定日期的记录'删除'命令。
delete
from table
where date(date) = '2015-06-01'
limit 1000
但是当我运行此命令时,我收到一个错误'锁的总数超过锁表大小'。我之前和当我更改innodb_buffer_poolsize时遇到此问题,它会解决问题,但这次甚至增加了这个数量,问题仍然存在。
我尝试了许多技巧,比如将限值改为100或甚至1条记录,但它不起作用。我甚至将innodb-buffer-poolsize增加到20GB,但没有任何改变
我还阅读了这些链接:
"The total number of locks exceeds the lock table size" Deleting 267 Records和
The total number of locks exceeds the lock table size
但他们并没有解决我的问题。我的服务器有64GB RAM
另一方面,我可以在特定日期不使用过滤器时删除记录:
delete
from table
limit 1000
我也可以毫无问题地选择当天的记录。
任何人都可以帮我这个吗?
我很感激任何帮助来解决这个问题。
答案 0 :(得分:1)
请勿使用date(date)
,否则无法使用INDEX(date)
。而只需使用date
并使索引以date
开头。
答案 1 :(得分:0)
date(date)要求数据库在运行时为数据库中所有17m行计算该列的值-DB将为17m行逐行创建date(date),然后创建表扫描(没有索引)这1700万行以得出结果集。这是您资源不足的地方。
您需要删除计算列的用法,这可以通过几种不同的方法解决。
将您的比较更改为: 日期> ='2015-06-01 00:00:00'和日期<='2015-06-01 23:59:59'
这现在将直接命中日期列上的索引(我假设您在此列上有一个索引,只是原始查询不会使用它)
另一种解决方案是在DATE类型的表中添加一列,并将每个DATETIME的DATE永久存储在该列中(并显然为新的DATE列添加索引)。这样一来,您无需指定时间范围,即可运行只希望检查DATE部分的任何查询。如果您当前还有其他查询使用date(date),则比起将时间范围添加到查询中,最好只包含一个仅包含日期的列(将时间范围添加到查询中比较好)。像这里的SELECT或DELETE,但可能不适用于涉及JOIN,GROUP BY等的其他查询。