它比这个查询更简单吗?
delete a.* from matches a
inner join matches b ON (a.uid = b.matcheduid)
是的,显然它确实......因为当matches
表格非常大时,上述查询的表现非常糟糕。
matches
约有2.2亿条记录。我希望这个DELETE查询的大小减少到大约15,000条记录。如何提高查询性能?我在两列都有索引。 UID和MatchedUID是此InnoDB表中仅有的两列,两者都是INT(10)无符号类型。该查询已在我的笔记本电脑(i7处理器)上运行超过14小时。
答案 0 :(得分:7)
删除这么多记录可能需要一段时间,我认为如果你这样做的话,这个速度就快了。如果您不想投资更快的硬件,我建议采用另一种方法:
如果你真的想要删除2.2亿条记录,那么该表只剩下15.000条记录,那就是所有条目的99,999%。为什么不
这样的事情可能会更快一点:
/* creating the new table */
CREATE TABLE matches_new
SELECT a.* FROM matches a
LEFT JOIN matches b ON (a.uid = b.matcheduid)
WHERE ISNULL (b.matcheduid)
/* renaming tables */
RENAME TABLE matches TO matches_old;
RENAME TABLE matches_new TO matches;
在此之后,您只需检查并创建所需的索引,如果仅处理15.000条记录,则应该相当快。
答案 1 :(得分:0)
运行解释选择a。*来自匹配内连接匹配b ON(a.uid = b.matcheduid)将解释你的索引如何存在和被使用
答案 2 :(得分:0)
我可能会把自己设置为在这里烤,但是在自联接中执行这样的删除操作时,查询是否必须在每次删除后重新计算连接索引?
虽然它很笨拙,但你可以考虑:
一个。创建一个临时表来存储由内连接产生的uid,然后加入到THAT,然后执行删除操作。
OR
B中。添加一个布尔(位)类型的列,使用连接标记每个匹配(此操作应该是FAST),然后使用:
DELETE * FROM matches WHERE YourBitFlagColumn = True
然后删除布尔列。
答案 3 :(得分:0)
您可能需要批量删除。您可以使用公用表表达式通过递归删除来做到这一点,或仅以一定的批处理大小对其进行迭代。