所以我想为一个项目做以下事情。
我有 3 张桌子。前两个现在关心我们(第三个是为了更好地理解):
author {id, name}
authorship {id, id1, id2}
paper {id, title}
authorship 将作者与论文连接起来,authorship.id1 指的是 author.id,authorship.id2 指的是 paper.id。
我想要做的是制作一个图表,其中包含每个作者的节点和由两位作者之间的共同论文数量决定的边。
w=1 - union_of_common_papers/intersection_of_common_papers
因此,我构建了一个(在 stackoverflow 的帮助下)一个 sql 脚本,该脚本返回所有共同作者的夫妇以及普通论文的联合数量和交集。之后,我将使用 java 中的数据。如下:
SELECT DISTINCT a1.name, a2.name, (
SELECT concat(count(a.id2), ',', count(DISTINCT a.id2))
FROM authorship a
WHERE a.id1=a1.id or a.id1=a2.id) as weight
FROM authorship au1
INNER JOIN authorship au2 ON au1.id2 = au2.id2 AND au1.id1 <> au2.id1
INNER JOIN author a1 ON au1.id1 = a1.id
INNER JOIN author a2 ON au2.id1 = a2.id;
这完成了我的工作并返回如下列表:
+-----------------+---------------------+---------+
| name | name | weight |
+-----------------+---------------------+---------+
| Kurt | Michael | 161,157 |
| Kurt | Miron | 138,134 |
| Kurt | Manish | 19,18 |
| Roy | Gregory | 21,20 |
| Roy | Richard | 74,71 |
....
其中重量我可以看到 2 个数字 a,b 其中 b 是交叉点,ba 是普通论文的并集。
但这需要很多时间。所有的开销都来自这个额外的子选择
(SELECT concat(count(a.id2), ',', count(DISTINCT a.id2))
FROM authorship a
WHERE a.id1=a1.id or a.id1=a2.id) as weight
如果没有这条线,所有记录 (1M+) 都会在不到 2 分钟的时间内返回。这条线 50 条记录需要超过 1.5 分钟
我通过命令行在 linux 上使用 mysql
有什么想法可以优化它吗?
- 作者拥有约 130,000 条记录
- 作者身份 ~1,300,000 条记录
- 查询应返回约 1,200,000 条记录
这就是这个查询的解释返回值。不知道怎么用。
+----+--------------------+-------+--------+---------------------+-----------+---------+--------------+---------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+---------------------+-----------+---------+--------------+---------+-----------------+
| 1 | PRIMARY | a1 | ALL | PRIMARY | NULL | NULL | NULL | 124768 | Using temporary |
| 1 | PRIMARY | au1 | ref | NewIndex1,NewIndex2 | NewIndex1 | 5 | dblp.a1.ID | 4 | Using where |
| 1 | PRIMARY | au2 | ref | NewIndex1,NewIndex2 | NewIndex2 | 5 | dblp.au1.id2 | 1 | Using where |
| 1 | PRIMARY | a2 | eq_ref | PRIMARY | PRIMARY | 4 | dblp.au2.id1 | 1 | |
| 2 | DEPENDENT SUBQUERY | a | ALL | NewIndex1 | NULL | NULL | NULL | 1268557 | Using where |
+----+--------------------+-------+--------+---------------------+-----------+---------+--------------+---------+-----------------+