我有两个表:users
和user_friends
,users
表上有1:1反射联接。 (即user_friends
条记录类似于[user_id, friend_id]
,[friend_id, user_id]
)。
让我们说我有一个名为“self”的用户。我想要做的是找到所有与“self”共同拥有共同朋友并且在users表中符合其他一些简单条件的用户。这是迄今为止我提出的最好的,大约18秒钟。
可以改进此查询吗?
SELECT
DISTINCT(friend_id)
FROM
user_friends, users
WHERE
users.id != #{self.id}
AND (
signed_up IS NOT NULL
OR
user_id IN (
SELECT
friend_id
FROM
user_friends
WHERE
user_id = #{self.id}
)
)
AND
users.id = friend_id
AND
relationship_status = 'Single'
AND
current_location_id IS NOT NULL
;
此外,此处是此查询的EXPLAIN PLAN
。 “临时”表是否会导致问题?
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: user_friends
type: index
possible_keys: NULL
key: PRIMARY
key_len: 16
ref: NULL
rows: 1316316
Extra: Using where; Using index; Using temporary
*************************** 2. row ***************************
id: 1
select_type: PRIMARY
table: users
type: eq_ref
possible_keys: PRIMARY,fk_users_current_location_id
key: PRIMARY
key_len: 8
ref: yoke_int.user_friends.friend_id
rows: 1
Extra: Using where; Distinct
*************************** 3. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: user_friends
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 16
ref: const,func
rows: 1
Extra: Using index
答案 0 :(得分:3)
有几种方法可以改善您的查询。
JOIN
而不是从两个表中过滤。AND
,以便更简单的短路更快,停止子查询经常运行。<强>代码:强>
SELECT
DISTINCT(friend_id)
FROM
user_friends
JOIN users on users.id = friend_id
WHERE
users.id != #{self.id}
AND
relationship_status = 'Single'
AND
current_location_id IS NOT NULL
AND (
signed_up IS NOT NULL
OR
user_id IN (
SELECT
friend_id
FROM
user_friends
WHERE
user_id = #{self.id}
)
)
;