我在一个mysql表1中保存了一组节点,在另一个mysql表(表2)中保存了一个边表。节点带有主键,边使用这个“外键”
**table1**
id label
1 node1
2 node2
3 node3
**table2**
FK_first FK_sec rel
1 3 guardian
2 1 guardian
1 3 times
我知道数据库设计并不完美,但它很简单...... 现在我想要每个节点的“rel”数量并执行如下查询:
SELECT
label,
COUNT( rel ) as freq
FROM
`table1`
LEFT JOIN table2 ON (id=FK_first OR id=FK_second)
GROUP BY label
ORDER BY freq DESC
我有大约 1000 个节点和 2000 个边。如果查询设置为 ON(id=FK_first OR id=FK_second),则查询速度会更快(<1 秒)。另一个查询大约需要 6 秒,速度非常慢。
我希望得到一些评论来加快速度:-)
- LEFT JOIN table2 ON(id=FK_first 或 id=FK_second)~6 秒
- LEFT JOIN table2 ON (id=FK_first) ~0.16 秒
LEFT JOIN table2 ON (id=FK_second) ~0.16 秒
LEFT JOIN table2 ON id IN (FK_first,FK_second) ~6 秒
EXPLAIN 1: id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE table1 ALL NULL NULL NULL NULL 2571 Using temporary; Using filesort 1 SIMPLE table2 ALL FK_first,FK_second,FK_first_2 NULL NULL NULL 3858 EXPLAIN 2: id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE table1 index NULL PRIMARY 2 NULL 2571 Using index; Using temporary; Using filesort 1 SIMPLE table2 ref FK_first,FK_first_2 FK_first_2 4 table1.id 1
最佳答案
尝试进行两次连接并将“OR”移动到 COUNT() 函数中:
对于每一行,此操作在 FK1 上连接 table2 一次,然后在 FK2 上再次连接(如果尚未通过 FK1 连接到该行)。然后在 COUNT 中,我们指定仅将任一连接的 rel 列作为非连接的行空。
SELECT
label,
COUNT( table2A.rel || table2B.rel ) as freq
FROM
`table1`
LEFT JOIN
table2 as table2A
ON id=table2A.FK_first
LEFT JOIN
table2 as table2B
ON id=table2B.FK_second
AND table2A.FKFirst != table2B.FKFirst
GROUP BY label
ORDER BY freq DESC
关于mysql join性能IF多个OR条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11472232/