2012-01-05 7 views
0

에 '임시 사용'피하십시오 :내가 두 테이블, <code>users</code> 및 <code>followers</code>이 MySQL을 어떤 경우

users :

id   INT, PRIMARY_KEY 
name  VARCHAR 
joined  INT 

이 표는 idjoined에 색인됩니다.

테이블 '추종자'

user  INT 
follows  INT 

이 표는 usersfollows에 색인이 생성됩니다.

이 쿼리는 특정 시간 이후에 가입 한 특정 사용자가 뒤 따르는 모든 사용자의 이름을 찾습니다. 결과는 역순으로 이어야합니다.

id  key    extra 
----------------------------------- 
u  joined   Using where 
f  follows   Using index 

지금까지 너무 좋은 : 사용자 X가 추종자의 수가 많은 경우

SELECT u.name 
FROM users u, followers f 
WHERE f.user = X 
AND f.follows = u.id 
AND u.joined > 1234 
ORDER BY u.joined DESC 

지금, EXPLAIN

다음과 같은 수 있습니다. ('using'은 내가 간결하게하기 위해 제거한 다른 절들 때문입니다.) 사용자 X가 추종자의 작은 숫자가있는 경우

그러나, 이런 일이 발생 :

id  key    extra 
----------------------------------- 
f  follows   Using temporary, using filesort 
u  joined   Using where 

나는 ORDER BY를 생략하면, 내가 얻을 :

id  key    extra 
----------------------------------- 
f  follows   
u  joined   Using where 

MySQL의 최적화는 검사 것으로 보인다 처리해야하는 행의 수이며, 작을 경우 followers 테이블을 먼저 처리해야합니다. 최적화 단계에서 ORDER BY을 무시한 것으로 보입니다. 임시 테이블에 으로 인해 쿼리 속도가 느려집니다.

내 질문에 : MySQL이 테이블 검색을 수행하는 순서를 강제 할 수 있습니까? 가능성이있는 경우 이것이 가능하지 않습니다. using temporary을 제거 할 다른 방법이 있습니까?

+0

느린 쿼리를 통해 얼마나 많은 레코드를 얻을 수 있습니까? 사용자가 팔로어를 소량 가지고있을 때 당신이 사용합니까? –

+0

아마 약 100; 많은 수천이 될 수 있습니다. – Graham

+0

귀하의 질의가 다음과 같으면 어떻게됩니까 :'SELECT u.유 INNER는 = u.id WHERE f.user = 'XXX' 및 u.joined> 1234 u.joined DESC' –

답변

2

MySQL에서는 제공 한 순서대로 테이블 간의 조인을 수행하는 "STRAIGHT_JOIN"절을 제공합니다. 당신은 하나의 특정 "추종자 사용자"를 찾고 있기 때문에 정면 추종자 테이블을 놓고 그에서 가입 ...

SELECT STRAIGHT_JOIN 
     u.name 
    from 
    followers f 
     join Users u 
      on f.follows = u.id 
      and u.joined > 1234 
    where 
    f.user = X 
    order by 
    u.joined DESC 

같은 것을보십시오이는 "추종자"테이블과 사용자 ID에 대한 특정 시작 강제적으로 = X를 입력 한 다음 f.user = X에서 반환 된 행을 기준으로 SECONDARY로 users 테이블에 조인합니다. Followers 테이블에 "user"가 첫 번째 위치에있는 인덱스가 있는지 확인하십시오 (두 열의 인덱스가 (사용자, 다음)이어야합니다 (사용자, 팔로우). 쿼리 기반에서 가장 작은 단위는 가장 먼저 묻는 한 사람입니다.

+0

Excellent - 나는 straight_join에 대해 들어 보지 못했지만 정확히 무엇이 필요한지 알고 있습니다. 많은 감사합니다. – Graham