如何以最佳方式按两列进行 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 和计数?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - 在一个查询中按两列计数[重复]

使用group by时如何计算列中的行数

PowerPivot Group By 以查找值的计数

如何在 django 中将两列与 group by 相乘和求和

如何在R中一次按两列对行进行排名?

使用 GROUP BY 时如何选择分区内的最佳行