在大表上简单的mysql查询优化

时间:2014-10-02 09:02:14

标签: php mysql sql

我有一个简单的查询,需要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秒。谢谢!

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_idc.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。可能会更快