简体   繁体   English

在MySQL中优化查询-联接和子查询?

[英]Optimizing query in MySQL- joins and subqueries?

I have several tables: a table of users, and tables recording various actions they can take (ie downloading, reading, quiz, etc.). 我有几个表:一个用户表和一个记录他们可以执行的各种操作(即下载,阅读,测验等)的表。 I am trying to produce a table listing each individual user, and the number of actions they have taken thus far. 我正在尝试生成一个表格,列出每个用户以及他们迄今为止采取的行动数量。

SELECT a.user_id, b.action1 + c.action2 + d.action3 AS actions
FROM table_of_applicable_users a
LEFT JOIN 
    (SELECT DISTINCT e.user_id , COUNT( e.user_id ) AS action1
    FROM table_of_actions1 e
    JOIN user_records f ON f.user_id = e.user_id
    WHERE f.group_id =15
    GROUP BY e.user_id )b
LEFT JOIN 
    (SELECT DISTINCT g.user_id , COUNT( g.user_id ) AS action2
    FROM table_of_actions2 g
    JOIN user_records h ON h.user_id = g.user_id
    WHERE h.company_id =15
    GROUP BY g.user_id )c
LEFT JOIN 
    (SELECT DISTINCT i.user_id , COUNT( i.user_id ) AS action3
    FROM table_of_actions3 i
    JOIN user_records j ON j.user_id = i.user_id
    WHERE j.company_id =15
    GROUP BY user_id )d
JOIN user_records z ON z.user_id = a.user_id
WHERE z.group_id =15
GROUP BY a.user_id

I join the user records table in each sub-query because I found it reduces the number of rows by approximately half. 我在每个子查询中加入了用户记录表,因为我发现它使行数减少了大约一半。 However, the query still takes far too much time. 但是,查询仍然花费太多时间。 How might I further optimize this query, or create a new query that returns similar results? 如何进一步优化此查询,或创建一个返回相似结果的新查询?

ps The desired format for the results is as follows: ps结果的所需格式如下:

user_id    number of actions
00001      459
00002      2461, etc.

I am trying to understand your requirement, Things that i remove from my query i found to be uneccessary . 我试图了解您的要求,发现从查询中删除的东西是不必要的。

Select user_id,action1+action2+action3 AS actions from
(
SELECT  e.user_id , COUNT( e.user_id ) AS action1
    FROM table_of_actions1 e
    JOIN user_records f ON f.user_id = e.user_id
    WHERE f.group_id =15
    GROUP BY e.user_id

union all

SELECT  g.user_id , COUNT( g.user_id ) AS action2
    FROM table_of_actions2 g
    JOIN user_records h ON h.user_id = g.user_id
    WHERE h.company_id =15
    GROUP BY g.user_id 

union all
SELECT  i.user_id , COUNT( i.user_id ) AS action3
    FROM table_of_actions3 i
    JOIN user_records j ON j.user_id = i.user_id
    WHERE j.company_id =15
    GROUP BY user_id
)t4

Is userid column in table_of_actions1, table_of_actions2, table_of_actions3 and user_records is indexed ?. table_of_actions1,table_of_actions2,table_of_actions3和user_records中的userid列是否已索引? Try the following statement once 一次尝试以下语句

SELECT a.user_id, b.action1 + c.action2 + d.action3 AS actions FROM table_of_applicable_users a LEFT JOIN (SELECT DISTINCT e.user_id , COUNT( e.user_id ) AS action1 FROM table_of_actions1 e JOIN (SELECT user_id, group_id from user_records where group_id = 15) f ON f.user_id = e.user_id WHERE f.group_id =15 GROUP BY e.user_id )b LEFT JOIN (SELECT DISTINCT g.user_id , COUNT( g.user_id ) AS action2 FROM table_of_actions2 g JOIN (SELECT user_id, company_id from user_records where company_id= 15) h ON h.user_id = g.user_id WHERE h.company_id =15 GROUP BY g.user_id )c LEFT JOIN (SELECT DISTINCT i.user_id , COUNT( i.user_id ) AS action3 FROM table_of_actions3 i JOIN (SELECT user_id, company_id from user_records where company_id = 15) j ON j.user_id = i.user_id WHERE j.company_id =15 GROUP BY user_id )d JOIN user_records z ON z.user_id = a.user_id WHERE z.group_id =15 GROUP BY a.user_id

KumarHarsh was close. KumarHarsh接近了。 But a couple of fixes are needed: 但是需要一些修复:

Select user_id, SUM(actions) AS actions from  -- Note: SUM
(
( SELECT  e.user_id , COUNT(*) AS actions
    FROM table_of_actions1 e
    JOIN user_records f ON f.user_id = e.user_id
    WHERE f.group_id = 15
    GROUP BY e.user_id )
UNION ALL
( SELECT  g.user_id , COUNT(*) AS actions
    FROM table_of_actions2 g
    JOIN user_records h ON h.user_id = g.user_id
    WHERE h.company_id = 15
    GROUP BY g.user_id )
UNION ALL
( SELECT  i.user_id ,  COUNT(*) AS actions
    FROM table_of_actions2 j
    JOIN user_records j ON j.user_id = i.user_id
    WHERE j.company_id = 15
    GROUP BY user_id )
) t4
)
GROUP BY user_id;   -- Note: GROUP BY

But!... Because of the JOIN , the GROUP BY may give an excessive value for the COUNT . 但是!...由于有JOINGROUP BY可能会为COUNT赋予过多的值。 Recommend you check this to see if it gets the right count, or some inflated value: 建议您检查一下以查看其计数是否正确,或是否有虚高值:

SELECT e.user_id , COUNT(*) AS action1
    FROM table_of_actions1 e
    JOIN user_records f ON f.user_id = e.user_id
    WHERE f.group_id = 15
    GROUP BY e.user_id;

If it is inflated, then we will have to work a lot harder to make your query both fast and correct. 如果它膨胀了,那么我们将不得不付出更多的努力才能使您的查询既快速正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM