我正在尝试创建Friend of Friend网络,但是MySql查询需要很长时间才能运行(我的表有大约600万用户)。我是SQL编码的新手,所以我想知道是否有某种方法可以加速我的代码。
我正在尝试在Python(SqlAlchemy)上使用MySql创建一个Friend Friend网络。我的表名为“ projects”,具有两列Project_ID和Dev_ID。我将在同一项目中工作的两个开发人员定义为“朋友”。另外,“朋友的朋友”是指通过共同的朋友(但不是直接通过)与开发人员建立联系的人。
例如,考虑两个项目,其成员如下:
Project_ID Dev_ID
A 1
A 2
B 2
B 3
然后,我正在寻找创建如下所示的“朋友的朋友”表:
dev_ID project_ID FoF project_FoF
1 A 3 B
3 B 1 A
这意味着,对于dev_ID 1,{3}是一个FoF,因为在至少一个项目中1和3是通过{2}连接的,但是1和3不能一起工作。{2}没有任何FoF,因此它们未在输出表中列出。
我尝试实现的算法是,从“项目”表中给出4行A,B,C,D:
如果他们来自同一项目,则我加入A和B;如果他们具有相同的开发者,则我加入B和C;如果他们具有相同的项目,则我加入C和D。我确保A和B具有不同的开发人员,B和C具有不同的项目,C和D具有不同的开发人员。
importpandasaspd
pd.read_sql_query("""select DISTINCT A.project_id as project_1, D.project_id as project_FoF, A.dev_id as dev1, D.dev_id as FoF
from projects as A inner JOIN projects as B
on A.project_id=B.project_id
INNER JOIN projects as C
on B.dev_id=C.dev_id
INNER JOIN projects as D
on C.project_id=D.project_id
WHERE
A.dev_id!=D.dev_id AND B.dev_id != D.dev_id AND A.dev_id != B.dev_id AND A.project_id!=D.project_id""",engine)
对于较小的示例(例如,限制为10,000),该代码可以正常运行,但是对于非常大的数据库(约600万行),它会运行数小时,然后抛出错误,例如“ InterfaceError:(mysql.connector (.errors.InterfaceError)2013:查询期间与MySQL服务器的连接断开
如注释中所建议,这是EXPLAIN查询的输出。注意“ univ_dev_projects”与我上面的示例中的表Projects相同。EXPLAIN查询输出
这是针对同一张表的SHOW CREATE TABLE查询的输出:
创建表univ_dev_projects(\ nidint(11)NOT NULL AUTO_INCREMENT,\ ndev_idint(11)DEFAULT NULL,\ nproject_idint(11)DEFAULT NULL,\ n PRIMARY KEY(id),\ n KEYproject_id(project_id),\ n KEYuniv_dev_projects_dev_id_idx(dev_id)\ n)ENGINE = InnoDB AUTO_INCREMENT = 148532489 DEFAULT CHARSET = latin1
解决方案
暂无回答