-1

我正在使用以下查询,这真的很慢(大约需要 30-45 分钟)并且有时会卡住,并生成 500 错误,这对应用程序不利...

SELECT id, account_number, email, referred_by, dnt,
                             (SELECT count(*)
                              FROM tbl.registrations t2
                              WHERE t2.referred_by = t1.account_number
                             ) AS level1,
                             (SELECT count(*)
                              FROM  tbl.registrations t2 join
                                    tbl.registrations t3
                                    on t3.referred_by = t2.account_number
                              WHERE t2.referred_by = t1.account_number
                             ) AS level2,
                             (SELECT count(*)
                              FROM tbl.registrations t2 join
                                    tbl.registrations t3
                                    on t3.referred_by = t2.account_number join
                                    tbl.registrations t4
                                    on t4.referred_by = t3.account_number
                              WHERE t2.referred_by = t1.account_number
                             ) AS level3
                          FROM tbl.registrations t1 GROUP BY id;

我们在这个表中有大约 35000 行,数据库结构如下......

| id | account_number  | referred_by  |
+----+-----------------+--------------+
|  1 | ac01            | 5            |
+----+-----------------+--------------+
|  2 | ac02            | 5            |
+----+-----------------+--------------+
|  3 | ac03            | 4            |
+----+-----------------+--------------+

level1、level2、level3的计算如下...

total_referred - total number of members referred by account_number
total_reffered2 - total number of members that THEY(all accounts referred by account_number) all referred
total_reffered3 - total number of members that referred by all members of total_reffered2

例如

如果每个成员总是有 10 次推荐,那么...

level1 = 10
level2 = 100
level3 = 1000

请检查我做错了什么?请帮我重写这个查询或优化,顺便说一句我已经尝试添加索引。谢谢

4

1 回答 1

0

这是通过SQLFiddle的示例。我输入了一个包含 40 个条目的列表,其中包含引用它们的相应 ID,显示了以下的层次结构......

(hierarchy for 1)      (hierarchy for 2)   (hierarchy for 3)
    1                      2                   3
       4                      13                  21
          5                       14              22
          6                       15                  23
             31               16                         39
             32               17                         40
          7                       18                  24
       8                              35              25
          9                           36              26
          10                          37          27
          11                          38              28
             33                   19                  29
             34                   20                  30
          12

SQLFiddle 查询基于任何可能的引用引用创建 3 列。如果一个 ID 没有由其 ID 引用的帐户,则它们将没有值,需要使用 COALESCE 解析以防止出现空值。

select r.*,
       coalesce( presum.lvl1Cnt, 0 ) as Lvl1Total,
       coalesce( presum.lvl1cnt + presum.lvl2cnt, 0 ) as Lvl2Total,
       coalesce( presum.lvl1cnt + presum.lvl2cnt + presum.lvl3cnt, 0 ) as Lvl3Total
   from
      registrations r
         LEFT JOIN 
            ( SELECT 
                    r1.referred_by, 
                    count(distinct r1.id) as Lvl1Cnt,
                    count(distinct r2.id) as Lvl2Cnt,
                    count(distinct r3.id) as Lvl3Cnt
                 from 
                    registrations r1 
                       LEFT JOIN registrations r2 
                          ON r1.id = r2.referred_by 
                          LEFT JOIN registrations r3 
                             ON r2.id = r3.referred_by 
                 group by 
                    r1.referred_by ) presum
      ON r.id = presum.referred_by

假定内部查询全面完成一次。我只是确保您在 (referred_by, id) 上的表上有索引,以帮助优化按referred_by ID 值进行的分组

于 2013-08-29T19:56:54.823 回答