我必须根据某些条件从一个超过1亿行的表中删除大约10K行。当我执行查询时,大约需要5分钟。我运行了一个解释计划(delete
查询转换为select *
,因为MySQL不支持explain delete
)并且发现MySQL使用了错误的索引。
我的问题是:有没有办法告诉MySQL在删除过程中使用哪个索引?如果没有,我该怎么办?选择临时表然后从临时表中删除?
答案 0 :(得分:4)
有index hint syntax。 //ETA: sadly, not for deletes
ETA:
您是否尝试过ANALYZE TABLE $mytable
?
如果这没有回报,我认为你有2个选择:在删除之前删除有问题的索引并在之后重新创建它。或者将删除表连接到所需索引上的另一个表,该表应确保使用所需的索引。
答案 1 :(得分:2)
我从未真正遇到MySQL选择错误索引的情况,而是我对索引如何工作的理解通常是错误的。
您可能需要查看此书:http://oreilly.com/catalog/9780596003067
它有很多关于索引如何工作和其他调整选项的部分。
答案 2 :(得分:0)
如其他答案所述,MySQL不能使用索引,但可以使用PRIMARY KEY索引。
因此,最好的选择是,如果表上有PRIMARY KEY,则运行快速的SELECT,然后根据行删除。最好在TRANSACTION中使用,这样您就不会删除错误的行。
因此:
DELETE FROM table WHERE column_with_index = 0
将被重写:
SELECT primary_key FROM table WHERE column_with_index = 0
=>返回多行
DELETE FROM table WHERE primary_key IN(?, ?, ?)
=> ?
将替换为SELECTED主键的结果。
如果没有太多要删除的行,这种方式会更有效。
例如,我刚刚在同一张桌子上用相同的数据打了一个例子:
vs