2013-04-02 94 views
0

我有這樣的查詢來執行:MySQL查詢 - 幫助改進

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 

查詢工作,但問題是,實在是太慢了(在表用戶有43k行,沒有更多),大約需要10秒,由於計數(不同)的功能。有沒有辦法用更好的表現取代它?

感謝,

/盧卡

+0

你發佈了所有表的結構嗎?桌子上的索引是什麼? –

+0

您可以在查詢前添加「DESC」並將該查詢的輸出添加到您的問題中嗎?該查詢將顯示您在哪裏以及使用哪些密鑰。 –

回答

0

由於一些意想不到的笛卡爾結果,你可能會遭到破壞。我會嘗試以下。由於您的第一個內部聯接基於affiliate1條目必須存在,因此我會預先聚合這些聯繫人以獲得每個聯屬機構1條記錄,其中聯屬機構的標識加入用戶表,並僅獲取用戶類型!='1'的那些記錄。這基本上爲你創造你的計數DISTINCT。然後,加入到用戶表中以獲取用戶信息。然後,做一個類似的左連接,但對於第二個子公司(如果存在......也基於子公司的用戶類型!='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 
+0

工程就像一個魅力!非常感謝! –

0

您已經通過USER_ID分組和計數比它訂購。或者你可以簡單地使用DESC對它進行排序

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 
    INNER JOIN users AS u3 
    ON u1.userid = u3.affiliate2 
WHERE u1.usertypeid != '1' 
    and u2.signupdate between '2011-01-01 00:00:00' 
    and '2013-04-02 23:59:59' 
GROUP BY u1.userid DESC , u2.userid , u3.userid 
+0

謝謝...不幸的是,這個查詢仍然需要10秒 –

+0

@ Lucone83我已更新查詢。再試一次! –

+0

謝謝...這種方式可以消除至少一個不同的數字,這很好,但它仍然很慢(9秒)。你知道一種方法來取代其他計數(獨特)嗎? –