【问题标题】:MySQL, delete and index hintMySQL,删除和索引提示
【发布时间】:2011-02-24 20:43:50
【问题描述】:

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

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

【问题讨论】:

  • 确保您有一个主键,并且您的删除的 WHERE 子句中命名的列已编入索引。

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


【解决方案1】:

如其他答案所述,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 主键的结果替换。

如果你没有那么多行要删除,这样会更有效。

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

  • DELETE 分析了 7499067 行:12 秒

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

【讨论】:

    【解决方案2】:

    index hint syntax//ETA: sadly, not for deletes

    预计到达时间: 你试过运行ANALYZE TABLE $mytable吗?

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

    【讨论】:

    • 是的,但据我了解,索引提示不适用于删除语句。
    【解决方案3】:

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

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

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

    【讨论】:

    • +1,这本书让您大开眼界,看到许多您永远不会想到的事情。
    • 编辑,dnagirl 关于索引提示语法是对的,我不知道它上线了。
    • 我见过mysql多次选择错误的索引。对我们来说,它发生在一个有很多相似索引(15 个索引)的大表(15M 行)上。也许是一个疯狂的场景——这是有原因的——它经常得到错误的索引,即使选择的索引应该是 PRIMARY。
    • 从“我从未真正遇到过 MySQL 选择错误索引的情况”开始,很难相信答案。这不是一个罕见的问题。对于拥有数百万行数据库的数据库管理员来说,这是一个日常问题。
    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 2022-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    相关资源
    最近更新 更多