这里有一个简单的要求,即从Friend表中查询六度关系的量。
Friend的结构如下所示:
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| userId | int(11) | NO | MUL | NULL | |
| friendId | int(11) | NO | | NULL | |
+----------+---------+------+-----+---------+----------------+假设我想知道userId:1的六度关系量,我写下了六个查询,如下所示
SELECT friendId FROM Friend WHERE userId = 1来获得一个学位的朋友。
然后执行
SELECT friendId FROM Friend WHERE userId in (/*above query result*/)
五次。
问题并不像看起来那么简单,因为我的朋友表中有数百万条记录。
尽管用户在一个度关系中只有两个朋友,但他/她的六度关系量很有可能是1大于六位数。
in子句中的项数是指数级的。
然后,六个查询花费超过一分钟的时间来获得结果。
如何优化这种情况?
发布于 2015-11-25 22:19:04
您可以使用subqueries,看看MySQL优化器是否足够聪明,能够将它们重写为连接(通常是这样)。
但实际上RDBMS并不适合这项任务。最好研究一下基于图形的数据库。请参见this question示例。
发布于 2015-11-25 22:25:25
创建一个临时表来保存中间结果,并使用JOIN而不是IN:
DROP TEMPORARY TABLE IF EXISTS tmp_friends;
CREATE TEMPORARY TABLE `tmp_friends` (
`id` INT UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO tmp_friends VALUES(<id of the given user>);
#run this 6 times
INSERT IGNORE INTO tmp_friends
SELECT f.userId
FROM tmp_friends t
JOIN Friend f ON f.friendId = t.id
SELECT f.*
FROM tmp_friends t
JOIN Friend f ON f.userId = t.idhttps://stackoverflow.com/questions/33918706
复制相似问题