2014-01-08 46 views
3

我与数据库相当马虎,不能把这个与连接的工作,我甚至不能确定这将是更快......如何优化此DB操作?

DELETE FROM atable 
WHERE btable_id IN (SELECT id 
        FROM btable 
        WHERE param > 2) 
     AND ctable_id IN (SELECT id 
         FROM ctable 
         WHERE (someblob LIKE '%_ID1_%' 
            OR someblob LIKE '%_ID2_%')) 

Atable包含〜19M行,这将删除〜 3M的。目前,我只能使用LIMIT 100000运行查询,而且我不想整天坐在这里,因为每个删除(100.000行)运行大约1.5分钟。

任何方法来加速/自动化它?

的MySQL 5.5

(?你觉得它已经坏DB设计,如果任何表包含20M行)

+0

行数不是好坏表格设计的衡量标准。你的表是否正常化?这将是良好的餐桌设计的一种措施...... – Argeman

回答

2

使用EXISTSJOIN代替IN改善perfromance

使用EXISTS:

DELETE FROM Atable A 
WHERE EXISTS (SELECT 1 FROM Btable B WHERE A.Btable_id = B.id AND B.param > 2) AND 
     EXISTS (SELECT 1 FROM Ctable C WHERE A.Ctable_id = C.id AND (C.someblob LIKE '%_ID1_%' OR C.someblob LIKE '%_ID2_%')) 

使用JOIN:

DELETE A 
FROM Atable A 
INNER JOIN Btable B ON A.Btable_id = B.id AND B.param > 2 
INNER JOIN Ctable C WHERE A.Ctable_id = C.id AND (C.someblob LIKE '%_ID1_%' OR C.someblob LIKE '%_ID2_%') 
+0

带有'EXISTS'的那个似乎并没有改善事情,好吧,也许平均数秒。我的第二个问题是,我不能指定一个“LIMIT”,并且这样它就超时了。不管怎么说,多谢拉! – Innkeeper

1

除了优化查询,你也可以看看的好索引的使用,因为它们可能会阻止全表扫描。

对于BTable例如在id和param上创建一个索引。

解释为什么会有所帮助: 如果数据库必须以未排序的方式查找表中的id和param值,那么数据库必须读取所有行。如果数据库读取索引SORTED,它可以用降低的成本查找id和param。

1

首先,你应该试着用存在而不是in。在许多情况下它的速度更快。

然后,你可以尝试做内部连接,而不是在和存在。

例子:

delete a 
from a 
inner join b on b.id = a.tablebid 

最后,如果它可能是可能的(我不知道你是否有ID3,IDS)来改变或别的东西。有时奇怪和复杂的变化可以帮助优化器。时,子查询...

1

我看不到一个简单的索引会帮助很多。我会做:

delete from atable where id in (
    select 
     id 
    from 
     atable a 
     join btable b on a.btable_id = b.id 
     join ctable c on a.ctable_id = c.id 
    where 
     b.param > 2 
     and (
      c.someblob LIKE '%_ID1_%' 
      OR c.someblob LIKE '%_ID2_%' 
     ) 
) 

更正:我假设你已经有了BTABLE索引和ctable的ID的(可能是,如果他们是主键...)和b.param(如果它的数字)。