【问题标题】:MySQL delete statement optimizationMySQL删除语句优化
【发布时间】:2010-12-31 12:53:40
【问题描述】:

我有一些删除查询要针对一些非常大的表(~100 GB)运行,我想尽可能优化它们:

delete from table1 where column1 < date_sub(now(), interval 100 hour);

column1 是datetime 列,我假设为该列创建索引将加快删除速度。除此之外,我还能在这里做什么?使用date_sub() 函数会减慢查询速度吗?我应该在运行查询之前计算该值吗?

delete from table2 where column2 = x;

column2 是 table2 的主键,所以根据 mysql 文档它已经是一个索引。我的问题是:索引类型是PRIMARY,和INDEX 一样吗?我是否必须创建另一个类似INDEX 的索引才能加快速度?

delete from table3 where column3 = y;

table3 有一个复合主键,即 column3 和 column4。所以我有一个主键索引,但是由于删除查询不使用column4,我应该为column3创建一个单独的索引吗?还是组合主键可以做到?

我想这些都是非常基本的问题,但我找不到针对我的具体情况的明确答案,所以任何帮助将不胜感激!

【问题讨论】:

  • 您的第一步是在删除语句上使用EXPLAIN 并找出它在做什么。如果需要,请粘贴。
  • EXPLAIN 仅适用于 SELECT 语句(目前)。
  • 我认为 column1 是 DATETIME 而不是 DATE?否则使用一个小时的间隔会很愚蠢。
  • 好的,然后在等效的 SELECT 上执行 EXPLAINEXPLAIN SELECT * FROM table1 where column1 &lt; date_sub(now(), interval 100 hour);

标签: mysql optimization indexing sql-delete


【解决方案1】:

我假设为该列创建索引会加快删除速度。

不正确,因为需要更新相同的索引才能使索引具有任何值以供将来使用。

使用 date_sub() 函数会减慢查询速度吗?

不,这很好,因为它不是基于列值。对列值执行的函数可确保索引(如果存在于列上)无法使用。

索引种类是“PRIMARY”,和“INDEX”一样吗?

是的,主要部分确保该索引中的值也是唯一的。

我是否必须创建另一个“INDEX”类型的索引来加快速度?

不,你没有。 MySQL 还限制可以在单个表上定义的索引的总大小,具体取决于类型。 767 字节是 InnoDB 表的stated index prefix limitation; MyISAM 表是 1,000 字节。

table3 有一个复合主键,即 column3 和 column4。所以我有一个主键索引,但是由于删除查询不使用column4,我应该为column3创建一个单独的索引吗?还是组合主键可以做到?

测试两种设置并决定。我认为我自己不需要额外的索引。

【讨论】:

    【解决方案2】:

    如果您的DELETE 旨在消除该表中的绝大多数行,人们经常做的一件事是将您想要保留的行复制到重复表中,然后使用DROP TABLE 或@ 987654323@ 更快地清除原始表。

    索引可能有助于找到您需要删除的行,但删除需要更新索引。删除大量行后,索引可能不平衡,需要使用OPTIMIZE TABLE进行一些维护。

    DATE_SUB() 函数是一个常量表达式(它不会逐行变化),因此查询优化器应该足够聪明,可以将其分解并执行一次计算。

    您不需要为主键创建额外的索引。主键约束隐式创建一个索引,该索引提供与非主键索引相同的好处。

    如果您的搜索条件引用索引的最左侧列,则复合索引可能与单列索引一样有用。 “可能”的警告是由于单个索引节点较大,因此缓存索引需要更多内存,但这是一个足够小的因素,我不会创建一个完整的其他单列索引。

    【讨论】:

      猜你喜欢
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2016-10-06
      相关资源
      最近更新 更多