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

时间:2015-01-09 01:31:37

标签: 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条记录。第二次连接查询需要很长时间。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

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

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