MySQL删除语句优化

时间:2009-12-31 22:47:49

标签: mysql optimization indexing sql-delete

我有一些删除查询来运行一些非常大的表(~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创建一个单独的索引吗?或者组合的主键会这样做吗?

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

2 个答案:

答案 0 :(得分:10)

如果您的DELETE旨在消除该表中的绝大多数行,那么人们经常做的一件事就是将您要保留的行复制到重复的表中,然后使用{{1}或} DROP TABLE可以更快地消灭原始表格。

索引可能有助于查找需要删除的行,但删除需要更新索引。删除大量行后,索引可能会失衡,需要对TRUNCATE进行一些维护。

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

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

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

答案 1 :(得分:2)

  

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

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

  

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

不,没关系,因为它不是基于列值。对列值执行的函数可确保无法使用列中存在的索引。

  

索引类型是“PRIMARY”,与“INDEX”相同吗?

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

  

我是否必须制作另一种“INDEX”索引来加速?

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

  

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

测试两个设置&amp;决定。我不认为我自己需要额外的索引。