我有一个查询在mysql中使用一个非常慢的子查询,需要几分钟,而我所做的所有其他查询都非常快。
正如我发现subquerys很可能是一个坏主意,所以我想转换 这个子查询与我所做的所有其他查询一样,使用了对性能有重大影响的subquerys。
我的大多数其他查询都非常简单,但是这个让我疯狂。
这是一个例子。
我有客户和账单。客户有多个账单。法案有州。票据有一个参数“无论如何”。
我需要更新 “所有账单都处于状态1或2且所有账单都不是2的客户”
因为我无法找到如何做到这一点,我使用了反转 “所有没有账单的客户都没有处于状态1,而不是状态2并且账单无关 - 参数不是2”
这是我正在使用的subquerys的两个变体,一个使用count而一个使用“not in”,但它们似乎同样慢。
update client cl , bill bi
set cl.parameter = "parameter1"
where cl.parameter="parameter2"
and bi.whatever != "2"
and bi.client_id = cl.id
and (select count(cl.id)
from bill bi
where bi.client_id = cl.id
and bi.state!="state0"
and bi.state != "state1"
) = 0;
在mysql状态“发送数据”中变慢
update client cl , bill bi
set cl.parameter = "parameter1"
where cl.parameter="parameter2"
and bi.whatever != "2"
and bi.client_id = cl.id
and cl.id not in (select distinct cl.id
from bill bi
where bi.client_id = cl.id
and ( bi.state!="state1"
and bi.state != "state2"
) ;
在mysql状态“复制到临时表”时变慢了
我试了好几个小时,但是如果没有那么缓慢的子查询,我无法将其转换为有用的东西。 任何人都可以让我知道如何使用连接或比现在更快的东西这样做?
更新
感谢DRapp,这会产生完全相同的结果并且速度更快。对于我现在可以测试的内容,查询时间可以缩短到几秒钟,而且还需要几分钟。
select
c.id,
sum( if( b.State IN ( "State1", "State2" ), 1, 0 )) as OkStatesCnt,
sum( if( b.State NOT IN ( "State1", "State2" ) or b.whatever=2, 1, 0 ) ) as AnyOtherState
from
client c
join bill b
ON c.id = b.client_id
where
c.parameter = "parameter2"
group by
c.id
having
OkStatesCnt > 0
AND AnyOtherState = 0
和
UPDATE client cl,
( full select query from above ) as PreQualified
set cl.parameter = "parameter1"
where cl.id = PreQualified.id
答案 0 :(得分:0)
要预先确保包含哪些客户,您可以自行运行此查询...
select
c.id,
sum( if( b.State IN ( "State1", "State2" ), 1, 0 )) as OkStatesCnt,
sum( if( b.State IN ( "State1", "State2" ), 0, 1 )) as AnyOtherState
from
client c
join bill b
ON c.id = b.client_id
AND b.whatever != "2"
where
c.parameter = "parameter2"
group by
c.id
having
OkStatesCnt > 0
AND AnyOtherState = 0
如果这实际上是您正在寻找的内容,您可以像
一样实施更新UPDATE client cl,
( full select query from above ) as PreQualified
set cl.parameter = "parameter1"
where cl.id = PreQualified.id