有一个简单的要求是从You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'events.sched_expired < '2015-11-25' THEN '0' ' at line 4
表中查询六度关系的数量。
UPDATE events SET events.scheduled = ( CASE sched_exp_type WHEN 'counter' and events.sched_counter <= '0' THEN '0' WHEN 'date' events.sched_expired < '2015-11-25' THEN '0' ELSE (events.scheduled) END )
的结构是这样的:
$c_date = date("Y-m-d");
echo $c_date."<br/>";
$update_sched_column = "UPDATE events SET events.scheduled = (
CASE sched_exp_type
WHEN 'counter' and events.sched_counter <= '0' THEN '0'
WHEN 'date' events.sched_expired < '$c_date' THEN '0'
ELSE (events.scheduled)
END
)";
假设我想知道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 | |
+----------+---------+------+-----+---------+----------------+
五次。
问题并不像看起来那么简单,因为我在Friend表中有数百万条记录。
用户userId:1
的六度关系数量很可能超过六位数,尽管他/她只有两个朋友处于一度关系。
IN子句中的项目数量是指数级的。
然后六个查询花了一分多钟才得到结果。
如何优化这种情况?
答案 0 :(得分:0)
您可以使用subqueries并查看MySQL优化器是否足够聪明,可以将它们重写为连接(通常是这样)。
但实际上RDBMS不适合这项任务。更好地了解基于图形的数据库。例如,请参阅this question。
答案 1 :(得分:0)
创建临时表以保存中间结果,并创建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.id