2011-01-16 1 views
2

나는 3 행과 MySQL의 InnoDB의 테이블, events,이 : 나는 어떤 범위 내에서 모든 이벤트를 얻기를 위해 간단한 쿼리를 작성했습니다MySQL 쿼리는 인덱스에 더 오래 걸립니까?

event_id ---> int 
start  ---> long 
end  ---> long 

을하는 다른 이벤트와 충돌 :

select a.* from events a, events b 
where a.event_id != b.event_id and 
     a.start < b.end and 
     b.start < a.end 

표 ~ 10K 행을 가지고 있으며 ~ 2 초 정도 걸립니다. 성능을 높이기 위해 표를 조정하려고 시도하면서 startend 열에 색인을 추가했습니다. 어떤 이유로 든이 극적으로 은 성능이이고 속도는 5x입니다. 누구든지이 색인을 추가하는 것이 나쁜 성능을 손상시키는 이유를 알고 있거나 아이디어가 있습니까?

답변

1

MySQL은 관련된 열을 살펴보고 인덱스가 쿼리를 향상시키는 데 도움이된다고 오해하고 있습니다. 그러나 문제는 인덱스가 시작 부분을 해결하지만 레코드 자체를 해결해야만 a.event_id! = b.event_id를 해결할 수 있다는 점입니다.이 자체는 값 비싼 작업입니다.

인덱스가 없으면 크로스 조인과 필터가 필요하지 만 ​​많은 수의 임시 레코드가 표시 될 수 있지만 이는 훨씬 간단하고 직접적인 구현입니다.

쿼리가 시작 또는 종료에 대해 a 또는 b의 일부 범위로 바인딩되거나 테이블이 10k보다 큰 경우 매우 다른 그림이 될 수 있습니다. 인덱스를 유지해야하는 경우

, 당신은 인덱스를 무시 (당신이 알고있는 경우이 도움이) 특정 쿼리를 강제 할 수

select a.* 
from events a ignore index (index1) 
cross join events b ignore index (index1) 
where a.event_id != b.event_id and 
     a.start < b.end and 
     b.start < a.end 

인덱스가 index1의 이름 가정. 어떤 경우 든 MySQL이 각 경우에 MySQL의 결과를 수집하는 방법을 보여주기 위해 쿼리 앞에 "EXPLAIN"을 추가하면 유용합니다 (인덱스가없고 인덱스가 있지만 인덱스는 있지만 무시됩니다)

+0

색인을 유지할 수있는 (다른 쿼리를 도울 수있는) 쿼리를 구조화 할 수있는 방법이 있지만 여전히 교차 조인과 필터를 수행 할 수 있습니까? – JaredC