mysql - 在 MySQL 中计算交叉表的有效方法是什么?

标签 mysql join optimization

我有一个名为 messages 的表,其中包含两列:userA 和 userB。

每个用户都有一个类型:typeA 或 typeB。

我想计算不同类型用户之间发送的消息数量的交叉表。用户也可以同时是 typeA 和 typeB。类型存储在不同的表中:(id:1, typeA), (id:2, typeB)

userA/userB | typeA | typeB
-----
typeA          2000    81348
-----
typeB         18348    12938

如何有效地做到这一点?假设我有 100000 条消息。如果我为 userA 执行第一次内部联接:在最坏的情况下我会得到 7*100000 条记录。现在,如果我为 userB 执行第二次内部联接:我将获得 7*7*100000 条记录。第二个连接查询需要很长时间。

有更好的方法吗?

最佳答案

SELECT src.type AS `UserA/UserB`, SUM(dest.type = 'typeA') AS typeA, SUM(dest.type = 'typeB') AS typeB
FROM messages AS msgsrc
JOIN users AS src ON msgsrc.userA = src.id
JOIN messages AS msgdest ON msgsrc.userA = msgdest.userB
JOIN users AS dest ON msgdest.userB = dest.id
GROUP BY `UserA/UserB`

如果有更多类型的用户,只需继续添加更多 SUM(dest.type = 'TypeX') 列即可。

如果您不需要单独列中的总和,您可以这样做:

SELECT src.type AS srcType, dest.type AS destType, COUNT(*) AS count
FROM messages AS msgsrc
JOIN users AS src ON msgsrc.userA = src.id
JOIN messages AS msgdest ON msgsrc.userA = msgdest.userB
JOIN users AS dest ON msgdest.userB = dest.id
GROUP BY srcType, destType

这不需要修改来处理更多类型,并且可能会更有效,因为它不必生成那么大的中间表。

关于mysql - 在 MySQL 中计算交叉表的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27852517/

相关文章:

SELECT 中 date() 中的 MySQL 格式错误成功,但在 CREATE TABLE AS SELECT 中失败。那是对的吗?

mysql - Doctrine - 查询构建器使用数组设置参数(嵌套/多个值)

mysql - Eloquent ORM - 通过现有关系加入

mysql查询计数字段

c++ - 为什么当我重定向 stdout 时我的程序运行得更快?

database - 此优化是否始终有效

mysql - 如何优化datetime条件的查询?

mysql - 从两个表中获取总销售额数据

mysql - MySQL 中的列计数与值计数不匹配

mysql - MYSQL查找同名行