쿼리

2011-04-05 3 views
1
에 의해 조인 인덱스와 그룹을 설정하는 방법을

이의 우리가 공통 아래처럼 가입 있다고 가정 해 봅시다 :쿼리

EXPLAIN SELECT * 
FROM visited_links vl 
JOIN device_tracker dt ON (dt.Client_id = vl.Client_id 
AND dt.Device_id = vl.Device_id) 
GROUP BY dt.id 

것은 우리가 설명 실행하면, 그것은 말한다 :

id select_type table type possible_keys   key  key_len ref       rows Extra 
1 SIMPLE  vl  index NULL     vl_id  273  NULL      1977 Using index; Using temporary; Using filesort 
1 SIMPLE  dt  ref  Device_id,Device_id_2 Device_id 257  datumprotect.vl.device_id 4  Using where 

내가 아는 그룹화 기준을 사용할 때 올바른 색인을 선택하기가 어렵지만이 쿼리에서 'filesort를 사용하여 임시 사용'을 피하기 위해 설정할 수있는 색인은 무엇입니까? 왜 이런 일이 일어 났습니까? 특히 인덱스를 사용한 후에 이것이 발생하는 이유는 무엇입니까?

답변

0

당신은 당신의 인덱스를 게시하지 않았지만, 우선, 당신은 visited_links(client_id, device_id)에 대한 인덱스를 할 것이고, (client_id, device_id, id)device_tracker에 그 쿼리가 완전히 색인되어 있는지 확인 할 수 있습니다.

우수한 페이지 중 191부터는 High Performance MySQL, 2 판입니다. :

의 MySQL은 인덱스를 사용할 수 없습니다 전략 BY GROUP 두 가지 종류가 있습니다 : 그것은 그룹화를 수행하기 위해 임시 테이블이나 filesort를 사용할 수 있습니다. 쿼리에 따라 둘 중 하나가 더 효율적일 수 있습니다. 옵티 마이저가 SQL_BIG_RESULT 및 SQL_SMALL_RESULT 옵티 마이저 힌트를 사용하여 하나의 메소드 또는 다른 메소드를 선택하게 할 수 있습니다.

귀하의 경우, 제안 된 색인이 제공된 후에도 여러 개의 열을 결합하고 GROUP BY을 함께 사용하면 문제가 발생한다고 생각합니다. (a) 결합 조건 중 하나 또는 (b) GROUP BY을 제거하면 파일 포트가 필요하지 않습니다.

그러나 filesort가 항상 실제 파일을 사용하는 것은 아니며 결과 집합이 충분히 작 으면 메모리 버퍼 내에서 완전히 발생할 수 있으므로 성능 저하가 최소화 될 수 있습니다. 쿼리의 벽시계 시간도 고려하십시오.

HTH!

1

언급 할 점은 select (*이 경우)에 의해 반환 된 필드는 GROUP BY 절에 있거나 SUM() 또는 MAX() 같은 집계 함수를 사용해야한다는 것입니다. 그렇지 않으면 예기치 않은 결과가 발생할 수 있습니다. 이것은 데이터베이스가 group by 절에없는 필드를 선택하는 방법을 알지 못하면 그룹의 구성원을 얻을 수 있기 때문입니다.


내가 보는 방법은 쿼리를 비트로 나누는 것입니다.

  1. 당신이 그렇게 그 모든 필드는 해당 테이블에 인덱스한다 (dt.Client_id = vl.Client_id 및 dt.Device_id = vl.Device_id)에 가입해야합니다.

  2. 당신이

dt.id

를 포함하는 인덱스하지만 ...이 필요합니다, 그래서 당신은 dt.id에 의해 GROUP을 사용하는

(dt.client_id, dt.device_id에 대한 인덱스, dt.ID가) (dt.id, dt.client_id, dt.device_id) 조인에 대해 작동하지 않습니다에

인덱스는 GROUP BY에 대해 작동하지 않습니다.

때때로 인덱스를 사용할 수없는 쿼리로 끝나는 경우가 있습니다.

도 참조하십시오. http://ntsrikanth.blogspot.com/2007/11/sql-query-order-of-execution.html