使用分组依据和计数优化查询

时间:2019-10-10 14:20:49

标签: mysql sql

想要优化下面的查询的建议,因为根据选择的用户数量和日期范围,第一次运行目前大约需要20秒才能处理。

目的是为每个用户返回每个代码的计数。

有27个代码,每个用户都有一个上午和下午出勤记录。

SELECT user,
    code,
    COUNT(code) AS total
FROM attendances AS attendances
WHERE attendances.user IN ('abc123', 'abc456', 'abc789')
    AND (
        attendances.date >= '2019-10-06' AND attendances.date <= '2019-10-11'
    )
GROUP BY user, code

表定义

enter image description here

索引

每个字段都有一个索引

location
source_id
date
user_recorded
code
user

解释结果

enter image description here

1 个答案:

答案 0 :(得分:0)

对于此查询:

SELECT user, code,
       COUNT(code) AS total
FROM attendances a
WHERE a.user IN ('abc123', 'abc456', 'abc789') AND
      a.date >= '2019-10-06' AND a.date <= '2019-10-11'
GROUP BY user, code;

您有问题。 userdate上的索引都不会在索引中使用(在MySQL中)。

一种方法是union all,其索引位于(user, date, code)

(SELECT user, code, COUNT(*) AS total
 FROM attendances a
 WHERE a.user = 'abc123'
       a.date >= '2019-10-06' AND a.date <= '2019-10-11'
 GROUP BY user, code
) UNION ALL
(SELECT user, code, COUNT(*) AS total
 FROM attendances a
 WHERE a.user = 'abc456'
       a.date >= '2019-10-06' AND a.date <= '2019-10-11'
 GROUP BY user, code
) UNION ALL
(SELECT user, code, COUNT(*) AS total
 FROM attendances a
 WHERE a.user = 'abc789'
       a.date >= '2019-10-06' AND a.date <= '2019-10-11'
 GROUP BY user, code
);

这可以直接使用索引,并且应该快得多。