MySQL,删除和索引提示

时间:2010-05-27 20:33:14

标签: mysql query-optimization sql-delete sql-execution-plan

我必须根据某些条件从一个超过1亿行的表中删除大约10K行。当我执行查询时,大约需要5分钟。我运行了一个解释计划(delete查询转换为select *,因为MySQL不支持explain delete)并且发现MySQL使用了错误的索引。

我的问题是:有没有办法告诉MySQL在删除过程中使用哪个索引?如果没有,我该怎么办?选择临时表然后从临时表中删除?

3 个答案:

答案 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主键的结果。

如果没有太多要删除的行,这种方式会更有效。

例如,我刚刚在同一张桌子上用相同的数据打了一个例子:

  • 7499067通过DELETE分析的行:12秒

vs

  • 通过SELECT使用良好的索引进行分析的6行:0.10秒
  • 最后要删除的0行