2012-02-01 3 views
-1

users 테이블에 usersuser_friends과 1 : 1 반사 결합 테이블이 있습니다. (즉 user_friends 레코드는 [user_id, friend_id], [friend_id, user_id]과 같습니다.)이 SQL 쿼리의 성능을 향상시킬 수 있습니까?

"self"라는 사용자가 있습니다. 내가하려고하는 것은 "자기"와 공통된 공통의 친구가 있고 사용자 테이블의 다른 간단한 기준을 충족시키는 모든 사용자를 찾는 것입니다. 이것은 제가 지금까지 생각 해낸 것 중 최고입니다, 약 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

당신이 당신이 명확한 답이없는 현지화 된 질문을 왜 – galarant

+0

라고 코멘트를 남겨주세요 수 downvote하려는 경우. 그리고 당신의 타이틀은 당신이 다른 사람들이 당신의 일을하기를 바라는 것처럼 들립니다. 그건 그렇고 전 downvote하지 않았다. –

+0

확인 저스틴 의견에 감사드립니다. – galarant

답변

3

쿼리를 향상시키는 데는 몇 가지 방법이 있습니다.

  1. 두 테이블의 필터가 아닌 JOIN을 사용하십시오.
  2. 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} 
) 
) 
; 
관련 문제