【问题标题】:mysql innodb deletes 10000 rows by primary key, but no index is usedmysql innodb按主键删除10000行,但没有使用索引
【发布时间】:2020-05-11 03:51:34
【问题描述】:

我有一个使用InnoDB 存储引擎的MySQL 表。它包含大约 8000000 个数据行,当我使用时

delete from t where id in(1,2,3...) 

删除10000行数据,虽然id是主键,但没有提示主键索引。表t有6 indexes(Including primary key)。当我把SQL改成

select * from t where id in(1,2,3...)

它可以命中主键索引。当我减少参数删除5000行数据时,或者当我删除非主键索引但仍然删除10000行数据时,也可以命中主键索引。

mysql版本是5.7.27。 要删除的id是根据具体情况选择的,不是连续的。 当我尝试保留两个二级索引时,仍然可以使用主键索引。

为什么指定了主键值却没有命中索引?

deleted records的数量和secondary index的数量有什么关系?

【问题讨论】:

  • 哪个mysql版本?我怀疑你用过EXPLAIN {query} - 你能把它包括进来吗?你的id 总是连续的吗?为什么这里没有范围?围绕deleted recordssecondary index 的最后一个问题可能有更多的上下文需求需要理解这个问题。欢迎来到 SO
  • 版本是5.7.27
  • 要删除的id是根据具体情况选择的,不是连续的

标签: mysql indexing innodb sql-delete


【解决方案1】:

什么版本?较新的版本更改了处理长 IN 列表的两种方式之间的界限。

旧版本优化 UPDATEDELETESELECT 不同。

我不喜欢一次处理超过 1000 行。请注意,DELETESELECT 复杂得多。保存行的旧值以防出现ROLLBACK 或从崩溃中恢复。

你从哪里得到ids?最好将它们留在原处,并执行多表删除以从源中获取 id,而不是构建列表。

对于SELECT,使用二级索引和进行表扫描之间的分界线约为表的 20%。确切的截止值取决于统计数据和“成本”计算。

查看我关于大删除的其他提示:http://mysql.rjweb.org/doc.php/deletebig

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-12
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多