12

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

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

4

3 回答 3

4

索引提示语法//ETA: sadly, not for deletes

ETA:你试过跑步ANALYZE TABLE $mytable吗?

如果这没有得到回报,我认为您有 2 个选择:在删除之前删除有问题的索引并在之后重新创建它。或者将您的删除表加入所需索引上的另一个表,这应确保使用所需的索引。

于 2010-05-27T20:40:40.743 回答
1

我从来没有真正遇到过 MySQL 选择错误索引的情况,而是我对索引如何工作的理解通常是错误的。

你可能想看看这本书:http: //oreilly.com/catalog/9780596003067

它有一个关于索引如何工作和其他调整选项的精彩部分。

于 2010-05-27T20:41:15.643 回答
0

如其他答案所述,MySQL 不能使用索引,而是 PRIMARY KEY 索引。

所以你最好的选择,如果你在表上有一个主键是运行一个快速的选择,然后根据行删除。最好在 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 主键的结果替换。

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

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

  • DELETE 分析了 7499067 行:12 秒

对比

  • SELECT 使用良好索引分析 6 行:0.10 秒
  • 最后删除0行
于 2018-08-05T07:09:36.003 回答