0

私は実行するこのクエリを持っています:

SELECT u1.firstname,
       u1.lastname,
       u1.totalcommission,
       u1.userid,
       count(DISTINCT u2.userid) AS level1,
       count(DISTINCT u3.userid) AS level2
FROM users AS u1
INNER JOIN users AS u2 ON u1.userid = u2.affiliate1
AND u2.signupdate BETWEEN '2011-01-01 00:00:00' AND '2013-04-02 23:59:59'
LEFT JOIN users AS u3 ON u1.userid = u3.affiliate2
WHERE u1.usertypeid != '1'
GROUP BY u1.userid
ORDER BY count(DISTINCT u2.userid) DESC

テーブルのインデックス:

PRIMARY BTREE   Yes No  userid  41318   A   No  
email   BTREE   Yes No  email   41318   A   No  
affiliate1  BTREE   No  No  affiliate1  1967    A   Yes 
affiliate2  BTREE   No  No  affiliate2  258 A   Yes 
signupdate  BTREE   No  No  signupdate  41318   A   No

クエリは機能しますが、問題は本当に遅いことです (テーブル users には 43k 行があり、それ以上ありません)。count(distinct) 関数により、約 10 秒かかります。それをより高性能なものに置き換える方法はありますか?

ありがとう、

/ルカ

4

2 に答える 2

0

予想外のデカルト結果が原因で、おそらくクラッシュしている可能性があります。私は次のことを試してみます。最初の内部結合はアフィリエイト 1 エントリが存在する必要があることに基づいているため、アフィリエイトの ID がユーザー テーブルに結合され、ユーザー タイプ != '1' のレコードのみを取得するアフィリエイトごとに 1 つのレコードを取得するために、それらを事前に集計します。これにより、基本的にカウント DISTINCT が作成されます。次に、user テーブルに参加して、このアフィリエイトのユーザー情報を取得します。次に、同様の左結合を行いますが、2 番目のアフィリエイトに対して行います (存在する場合は、アフィリエイトのユーザー タイプ != '1' にも基づきます)。

これで、MAX でテーブルごとに 1:1 の比率が得られ、非常に高速になるはずです。

SELECT 
      u1.firstname,
      u1.lastname,
      u1.totalcommission,
      u1.userid,
      PreAggUA1.AffiliateUsers as Level1,
      PreAggUA2.AffiliateUsers as Level2
   FROM 
      ( select 
              ua1.affiliate1,
              count(*)  as AffiliateUsers
           from users ua1
              join users ua1b
                  on ua1.affiliate1 = ua1b.userid
                 and ua1b.userTypeID != '1'
              group by
                 ua1.affiliate1 ) as PreAggUA1

         JOIN Users u1
            on PreAggUA1.Affiliate1 = u1.UserID

         LEFT JOIN ( select 
                           ua2.affiliate2,
                           count(*)  as AffiliateUsers
                        from 
                           users ua2
                              join users ua2b
                                 on ua2.affiliate2 = ua2b.userid
                                and ua2b.userTypeID != '1'
                         group by
                            ua2.affiliate2 ) as PreAggUA2
            on PreAggUA1.Affiliate1 = PreAggUA2.Affiliate2
   ORDER BY 
      PreAggUA1.AffiliateUsers DESC
于 2013-04-02T10:57:15.867 に答える