如何以最佳方式按两列进行 GROUP BY 和计数?
Posted
技术标签:
【中文标题】如何以最佳方式按两列进行 GROUP BY 和计数?【英文标题】:How to GROUP BY and count by two columns optimally? 【发布时间】:2019-02-07 12:57:31 【问题描述】:我想对一个有两列具有相同值的大表进行数据计数。但以最好的方式
我有一个产品关联表,我想计算产品与另一个产品关联的次数,我想知道哪些关联最多,但是我的表太大,我想知道是否有优化的解决方案这个
我的桌子:
mysql> SELECT * FROM user_association_data_2019_02;
+----+------------+-------------+---------------------+---------+
| id | product_id | association | last_modified | user_id |
+----+------------+-------------+---------------------+---------+
| 6 | 1096 | 1355 | 2019-02-04 11:42:07 | 2940 |
| 17 | 1096 | 1758 | 2019-02-04 11:54:10 | 2940 |
| 19 | 1355 | 1758 | 2019-02-04 11:54:15 | 2940 |
| 24 | 1096 | 1758 | 2019-02-04 11:55:31 | 2940 |
| 37 | 1355 | 1758 | 2019-02-04 11:58:54 | 2940 |
| 53 | 1096 | 463 | 2019-02-04 16:38:49 | 2940 |
| 56 | 1758 | 560 | 2019-02-05 10:11:43 | 2940 |
| 57 | 1096 | 560 | 2019-02-05 10:11:45 | 2940 |
| 65 | 1096 | 560 | 2019-02-05 11:10:13 | 2940 |
| 70 | 1758 | 560 | 2019-02-05 12:11:50 | 2940 |
| 74 | 1758 | 560 | 2019-02-05 12:13:27 | 2940 |
| 75 | 1207 | 560 | 2019-02-05 12:13:30 | 2940 |
| 77 | 1096 | 560 | 2019-02-05 12:14:17 | 2940 |
| 79 | 1207 | 1355 | 2019-02-05 14:04:17 | 2940 |
| 81 | 1355 | 560 | 2019-02-06 14:17:25 | 2940 |
| 82 | 1096 | 560 | 2019-02-06 14:17:26 | 2940 |
这解决了我的计数
mysql> SELECT product_id, association, count(*) as total FROM user_association_data_2019_02 GROUP BY product_id, association;
+------------+-------------+-------+
| product_id | association | total |
+------------+-------------+-------+
| 1096 | 1355 | 1 |
| 1096 | 1758 | 2 |
| 1096 | 463 | 1 |
| 1096 | 560 | 4 |
| 1207 | 1355 | 1 |
| 1207 | 560 | 1 |
| 1355 | 1758 | 2 |
| 1355 | 560 | 1 |
| 1758 | 560 | 3 |
+------------+-------------+-------+
但是我不认为这是优化的,如何优化这个计数?
【问题讨论】:
当我读到这个user_association_data_2019_02
时,很明显你有一个规范化问题......一般的优化过程涉及创建索引,这意味着你需要索引user_association_data_2019_02 (product_id, association)
进行优化。如果 MySQL 使用的是索引,那么它可以执行到使用覆盖索引(所有数据都来自索引数据)。
【参考方案1】:
可能没有其他方法可以重写您的查询。但是你可以通过添加索引来提高性能:
ALTER TABLE t ADD INDEX ix_productid_association (product_id, association);
【讨论】:
这里看不懂index的用例。查询需要对整个表进行聚合。 从索引中获取数据通常更快,并且已经排序,因此分组更快。 我的查询没有 WHERE 但我需要添加一个 ORDER BY 以获得最相关的产品SELECT product_id, association, count (*) as total FROM user_association_data_2019_02 GROUP BY product_id, association ORDER BY total DESC;
不幸的是,索引不会使 order by count(*)
更快,但分组并找到 count(*) 会很快。
@Raymond Nijland 明白了!谢谢你的帮助,我试试以上是关于如何以最佳方式按两列进行 GROUP BY 和计数?的主要内容,如果未能解决你的问题,请参考以下文章