我对数据库很草率,不能用连接工作,我甚至不确定会更快......
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
运行查询,我不想整天坐在这里与phpmyadmin,因为每次删除(100.000行)大约运行1.5分钟。
有什么方法可以加快/自动化它?
MySQL 5.5
(如果任何表包含20M行,你认为它的DB设计已经很糟糕了吗?)
答案 0 :(得分:2)
使用EXISTS
或JOIN
代替IN
来提高效果
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_%'))
使用加入:
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_%')
答案 1 :(得分:1)
除了优化查询之外,您还可以查看索引的良好用法,因为它们可能会阻止全表扫描。
例如,对于BTable,在id和param上创建一个索引。
解释为什么这会有所帮助: 如果数据库必须以未排序的方式查找表中的id和param值,则数据库必须读取所有行。如果数据库读取索引SORTED,它可以以降低的成本查找id和param。
答案 2 :(得分:1)
首先你应该尝试使用exists而不是in。在许多情况下它会更快。
然后你可以尝试做内连接而不是in和exists。
示例:
delete a
from a
inner join b on b.id = a.tablebid
最后,如果可能(我不知道你是否有id3,ids)改变或通过别的东西。有时奇怪而复杂的变化有助于优化器。情况何时,子查询...
答案 3 :(得分: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(如果它是数字的话)。