优化包含左连接的sql查询

时间:2015-06-02 08:24:40

标签: mysql sql

我有一个名为errors的表,它具有以下结构:

错误

| id | UserID        | CrashDump   | ErrorCode| Timestamp
| 1  | user1         | Crash 1     | 100      | 2015-04-08 21:00:00 
| 2  | user2         | Crash 2     | 102      | 2015-04-10 22:00:00
| 3  | user3         | Crash 4     | 105      | 2015-05-08 12:00:00
| 4  | user4         | Crash 4     | 105      | 2015-06-02 21:22:00
| 5  | user4         | Crash 4     | 105      | 2015-06-03 04:16:00

我想获得包含以下数据的结果集:

所需的结果集

   CrashDump        | Error Count| Affected Users| 
    Crash 4         | 3          | 2             |  
    Crash 2         | 1          | 1             | 
    Crash 1         | 1          | 1             | 

结果集会将每个错误的计数保存为错误计数和受影响的用户(收到此错误的不同用户)。

我已经能够使用以下查询获得所需的结果,但事实证明它是非常耗费资源的,并且在庞大的数据集上MySQL崩溃。 您能否指导我如何优化我当前的查询或指导我更好地实现其逻辑?任何帮助将不胜感激。

当前查询:

select B.CrashDump as CrashDump, B.B_UID as affected users, C.C_UID as ErrorCount  
from
(
    Select count(A.UserID) as B_UID, A.CrashDump, (A.timestamp) as timestmp, 
    (a.errorcode) as errorCde, (a.ID) as uniqueId
    from
    (   
        select UserID , CrashDump, timestamp,errorcode,id
        from errors 
        where Timestamp >='2015-04-08 21:00:00' and Timestamp <='2015-06-10 08:18:15'
        group by userID,CrashDump
    ) as A
    group by A.CrashDump
) as B

left outer join 
(
    select CrashDump , count(UserID) as C_UID
    from errors 
    where Timestamp >='2015-04-08 21:00:00' and Timestamp <='2015-06-10 08:18:15'
    group by CrashDump
) as C

On B.CrashDump = C.CrashDump

order by ErrorCount desc limit 0,10

4 个答案:

答案 0 :(得分:3)

尝试

SELECT CrashDump, COUNT(ErrorCode) AS ErrorCount, COUNT(DISTINCT UserID) AS AffectedUser
FROM errors
WHERE Timestamp >='2015-04-08 21:00:00' AND Timestamp <='2015-06-10 08:18:15'
GROUP BY CrashDump

答案 1 :(得分:2)

你不能这样做吗?:

SELECT
    CrashDump,
    COUNT(ErrorCode) AS ErrorCount,
    COUNT(DISTINCT UserID) AS AffectedUsers
FROM
    Errors
WHERE 
    Timestamp >='2015-04-08 21:00:00' and Timestamp <='2015-06-10 08:18:15'
GROUP BY
    CrashDump

答案 2 :(得分:1)

SELECT CrashDump, SUM(e) AS "Error Count", MAX(u) AS "Affected Users"
FROM(
SELECT crashdump, count(errorcode) as e, count(userid) as u
FROM errors
WHERE Time_stamp BETWEEN '2015-04-08 21:00:00' and '2015-06-10 08:18:15'
GROUP BY crashdump, userid) a
GROUP BY crashdump
ORDER BY crashdump DESC

输出

crashdump   Error Count Affected Users
Crash 4     3           2
Crash 2     1           1
Crash 1     1           1

SQL FIDDLE:http://sqlfiddle.com/#!9/13eab/1/0

答案 3 :(得分:1)

这是有效的解决方案:

Select A.CrashDump, sum(A.ErrorCount) as ErrorC, count(A.AffectedUsers) 
From
(
SELECT
    CrashDump,
    COUNT(ErrorCode) AS ErrorCount,
    COUNT(DISTINCT UserID) AS AffectedUsers, UserID
FROM
    errors
WHERE 
    Timestamp >='2015-05-13 10:00:00' and Timestamp <='2015-05-14 03:07:00'

GROUP BY
    CrashDump, userID
) AS A
group by A.CrashDump

order by ErrorC desc limit 0,10

感谢大家帮助实现理想的结果。