如何加快我的简单SQL查询

时间:2013-02-26 09:10:00

标签: sql sql-subselect

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);

我知道这是一个非常简单的声明,它立即出现在我的测试服务器中,但是在我的生产服务器上运行它需要永远。我应该如何更改它以加快速度?

2 个答案:

答案 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)中涉及的任何其他列创建索引。这应该加快大表上的选择查询(但减慢了写作速度,所以如果你的应用程序是密集的,你必须找到妥协)。