select id,firstname,lastname,email,country,portal,language
from totaluser
where userid in
(select user from (select user, shipping / NULLIF(goodsvalue,0) as difference
from shipment
where user in
(select user
from (select user, count(*) as shipcount
from shipment
where user in
(select user from shipment
where status in ('3','5')
and createdtime between '2012-01-01'
and '2013-02-22' group by user)
and status in ('3','5') group by user)
as a
where status in ('3','5')
and shipcount=1))
as b
where difference > 2.5);
我知道这是一个非常简单的声明,它立即出现在我的测试服务器中,但是在我的生产服务器上运行它需要永远。我应该如何更改它以加快速度?
答案 0 :(得分:1)
尝试此查询
select tu.id, tu.firstname, tu.lastname, tu.email, tu.country, tu.portal, tu.language
from totaluser tu,
(select user
from shipment
where status in ('3','5')
and createdtime between '2012-01-01'
and '2013-02-22' and status in ('3','5')
group by user
HAVING count(*) = 1 AND shipping / NULLIF(goodsvalue,0) > 2.5) s
where tu.userid = s.user;
我尝试从装运表中删除您正在创建的子查询嵌套,并创建了一个与totaluser表连接的对象集合。
答案 1 :(得分:1)
您的查询看起来非常混乱。如果我理解正确,它就是这样做的:
SELECT id,firstname,lastname,email,country,portal,language FROM totaluser LEFT JOIN
(SELECT user,COUNT(*) AS shipcount FROM shipment
WHERE
createdtime BETWEEN '2012-01-01' AND '2013-02-22' AND
status IN ('3','5') AND
shipping / NULLIF(goodsvalue,0) > 2.5
GROUP BY user) AS condid
ON totaluser.id=condid.user
WHERE condid.shipcount = 1;
(您可以使用this fiddle来测试我是否正确)
我建议您使用CREATE INDEX索引user
上的列shipment
,并且通常还会为where子句(id,status和createdtime)中涉及的任何其他列创建索引。这应该加快大表上的选择查询(但减慢了写作速度,所以如果你的应用程序是密集的,你必须找到妥协)。