我有一些删除查询来运行一些非常大的表(~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创建一个单独的索引吗?或者组合的主键会这样做吗?
我想这些都是非常基本的问题,但我无法找到针对我的情况的明确答案,所以任何帮助都将不胜感激!
答案 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;决定。我不认为我自己需要额外的索引。