mySQL删除查询优化

mySQL删除查询优化,mysql,Mysql,我有两张桌子:食物和啤酒 foos在开始日期编制索引 moos将foos.id作为外键 foos拥有数百万条记录。moos不是10万张唱片 我需要做一件非常简单的事情:从foos中删除开始日期

我有两张桌子:食物和啤酒

foos在开始日期编制索引 moos将foos.id作为外键 foos拥有数百万条记录。moos不是10万张唱片

我需要做一件非常简单的事情:从foos中删除开始日期
delete foos FROM foos LEFT JOIN moos ON foos.id = moos.foo_id WHERE moos.foo_id is null AND foos.start_date < "2013-05-30";

delete foos FROM foos WHERE start_date < "2013-05-30" AND id NOT IN (select foo_id from moos where foo_id is not null);
我要补充:

我总是选择X,这样我就知道开始日期 只有几千个moo引用了foo

我使用的是mySQL 5.5,所以我无法解释删除,但当我用select 1替换时,解释表明mySQL正在做我认为应该做的事情:

首先使用start_date索引查找正确的foo 那么看看穆斯 所以这不应该是一个如此漫长的交易… 有没有更好的方法,或者我遗漏了什么

谢谢

PJ

那么

CREATE TABLE foos_new
SELECT *
FROM
    foos
LEFT JOIN moos on foos.id = moos.foo_id
WHERE
    moos.foo_id IS NOT NULL
    OR
    (
        moos.foo_id IS NULL AND
        foos.start_date >= "2013-05-30"
    );
然后删除原始表并将新表重命名为foos。当然,还要添加任何索引。

另一个想法:


如果执行级联删除,则外键可能是问题所在。对于来自foo的每个删除,它还必须检查moo,以查看现在是否存在任何孤立记录。是的,不需要这样做,因为您只删除不匹配的,但查询计划器可能没有那么聪明。

查询1不起作用,因为foos.id=moos.foo\u id仅在moos.foo\u id不为空时才起作用。NULL与包括NULL的任何内容进行比较,结果为false。并且添加moos.foo_id为null将导致没有与该条件匹配的记录

我不认为查询2有任何不起作用的原因。在foo_id不为空的moos中选择foo_id需要多长时间?我想补充一下

查询2也可以重写为

delete foos FROM foos
WHERE start_date < "2013-05-30" 
  AND exists (select foo_id from moos where foo_id = foos.id);

最后,我在foo_id上的Moos表中添加了一个索引,解决了这个问题。 考虑到Moos不是一张大桌子,我不知道为什么有必要说实话

谢谢大家花时间帮忙


PJ

moos.foo_id是否为空?为什么加入空字段我不确定我是否遵循-这是一个左连接,所以应该不会有问题,对吗?开始日期是否有索引?我并不想过时,为什么不在查询限制05000上设置一个限制,然后执行一个查询,以查看是否仍有链接数据,并获取表中剩余的数据量。当然,所有这些都是在一个while循环中进行的,同时保持总量!=0这只是一个临时解决方案的想法,除非您计划定期对数百万行数据执行此操作。在我找到答案之前,我会做很多临时工作,尽管我猜你会想要一个答案answer@neutrino:是的。Adsy2010不幸的是,我确实需要经常这样做…谢谢乔治。但我不确定它是否会更好——这意味着要复制数百万条记录……如果你有足够的空间进行实验,那么值得一试。据我所知,这种方法允许更多的顺序写入,比随机写入更快。谢谢Victor。不过,在您的第一条评论中:我非常肯定它是有效的,因为它是一个左连接。例如:呃,是的,它将用于外部连接。请让我知道子查询的运行时间并完成我的查询工作。是的,查询计划器一定有问题。我想我需要尝试并找到一个5.6安装来解释删除查询。