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

これは非常に単純なステートメントであり、テストサーバーではすぐに実行できることを理解していますが、本番サーバーで実行するには永遠に時間がかかります。スピードアップするにはどうすれば変更できますか?

4

2 に答える 2

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テーブルと結合するオブジェクトのコレクションを作成しようとしました。

于 2013-02-26T09:33:20.607 に答える
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;

このフィドルを使用して、私が正しいかどうかをテストできます)

CREATE INDEXを使用して の列userにインデックスを付けることをお勧めしますshipment。一般に、where 句 (id、status、createdtime) に関連する他の列のインデックスも作成します。これにより、大きなテーブルでの選択クエリが高速化されます (ただし、書き込みが遅くなるため、アプリが書き込みを集中的に行う場合は、妥協点を見つける必要があります)。

于 2013-02-26T10:06:34.920 に答える