2014-01-08 76 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(如果它的數字)。