我有一个简单的查询,需要2.5秒才能评估。我想优化它,但我不知道该怎么做。任何人都可以建议如何优化它? 接下来是逻辑:计算指定广告系列按引荐来源分组的所有点击次数。 下面有“解释”mysql查询。表单击,用户有很多行。
mysql> explain select count(*) as amount,ac.referrer from clicks ac
-> inner join users a on a.id = ac.user_id
-> where a.campaign_id = 26 group by ac.referrer
-> order by amount desc;
+----+-------------+-------+--------+-------------------+---------+---------+------------------------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------+---------+---------+------------------------+---------+---------------------------------+
| 1 | SIMPLE | ac | ALL | ac_adv | NULL | NULL | NULL | 1607031 | Using temporary; Using filesort |
| 1 | SIMPLE | a | eq_ref | PRIMARY,advoc_cam | PRIMARY | 4 | mydb.ac.user_id | 1 | Using where |
+----+-------------+-------+--------+-------------------+---------+---------+------------------------+---------+---------------------------------+
2 rows in set (0.00 sec)
修改
对不起,那没有提供shemas,但现在没有必要了。现在,我完全覆盖了已接受答案中建议的索引列。
这是添加索引(c.user_id,c.referrer)的正确解决方案。其他索引已经存在并且毫无意义。但现在查询在0.2秒内完成,而不是之前的2.5-3秒。谢谢!
答案 0 :(得分:0)
尝试
select count(a.user_id) as amount,ac.referrer
from users a
INNER JOIN clicks ac
on a.id = ac.user_id
where a.campaign_id = 26
group by ac.referrer
order by amount desc;
在用户表上使用字段(CAMPAIGN_ID, user_id)
- >这将遍历users表,然后为找到的每个用户添加点击。
答案 1 :(得分:0)
嗯,我可能会将您的查询重写为:
SELECT c.referrer,
count(*) amount,
FROM clicks c
JOIN users u
ON u.campaign_id = 26
AND u.id = c.user_id
GROUP BY c.referrer
ORDER BY amount DESC
只是要明确发生了什么。
您的基本查询与获取的内容一样好,因此您需要使用索引来提高性能。
对于用户加入,u.id
上的主键应该非常好,但您可以通过(u.campaign_id, u.id)
上的合成获得更好的效果。
对于主要表格点击,您应该尝试c.user_id
和c.referrer
上的索引以及两个可能的合成(c.user_id, c.referrer)
和(c.referrer, c.user_id)
。使用EXPLAIN计划计算出哪些是possible_keys并删除那些没有帮助的那些。
如果查询不使用它们,您可能必须提示某些索引,但它们会显示在possible_keys中(每个表或连接只能使用一个 - 计划的一行)。
在每个表上使用复合,其中两个索引覆盖所有四个引用列,例如(u.campaign_id, u.id)
和(c.user_id, c.referrer)
查询应该包含在索引中,而不需要访问可以进一步提高性能的表行。
还要记住,任何新索引都会减慢DML操作(INSERT,UPDATE,DELETE),其中包含索引引用的列,因此如果您的写入速率较高,那么对此查询执行命中可能会更好代替。
答案 2 :(得分:-1)
mysql> explain select count(*) as amount,ac.referrer from clicks ac
-> inner join users a on a.id = ac.user_id AND a.campaign_id = 26
-> group by ac.referrer
-> order by amount desc;
在查询中将WHERE更改为AND。可能会更快