2014-06-10 2 views
0

색인이 6 개입니다. 그러나 MySQL은 전체 색인을 절대로 사용하지 않습니다. 접두어 만 사용합니다.mysql이 모든 색인 열을 사용하지 않습니다

CREATE TABLE TestChannelData 
(
    hostId   MEDIUMINT UNSIGNED NOT NULL, 
    sessionId  MEDIUMINT UNSIGNED NOT NULL, 
    sessionFragment TINYINT UNSIGNED NOT NULL, 
    id    INT  UNSIGNED NOT NULL, 
    vcid   INT  UNSIGNED NULL, 
    dssId   SMALLINT UNSIGNED NOT NULL 
) ENGINE=InnoDB CHARSET=latin1; 

CREATE TABLE TestChannelValue 
(
    hostId   MEDIUMINT UNSIGNED NOT NULL, 
    sessionId  MEDIUMINT UNSIGNED NOT NULL, 
    sessionFragment TINYINT UNSIGNED NOT NULL, 
    id    INT  UNSIGNED NOT NULL, 
    ertCoarse  INT  UNSIGNED NOT NULL, 
    ertFine   INT  UNSIGNED NOT NULL 
) ENGINE=MyISAM CHARSET=latin1; 

ALTER TABLE TestChannelValue 
    ADD KEY reverseIndex(hostId, sessionId, sessionFragment, id), 
    ADD KEY ertReverseIndex(ertCoarse, ertFine, hostId, sessionId, sessionFragment, id); 

ALTER TABLE TestChannelValue 
ADD KEY reverseErtIndex(hostId, sessionId, sessionFragment, id, ertCoarse, ertFine); 

쿼리 :

SELECT cv.sessionId, cv.hostId, cv.sessionFragment, 
    cd.dssId, cd.vcid, 
    cv.ertCoarse, cv.ertFine 
    FROM TestChannelData AS cd 
    STRAIGHT_JOIN TestChannelValue AS cv USE INDEX (ertReverseIndex) 
    ON ((cv.sessionId  = cd.sessionId)  AND 
     (cv.hostId   = cd.hostId)   AND 
     (cv.sessionFragment = cd.sessionFragment) AND 
     (cv.id    = cd.id)) 
    WHERE 
     (
      (cv.ertCoarse > 0) AND 
      ((cv.ertCoarse < 2000) OR ((cv.ertCoarse = 2000) AND (cv.ertFine = 0))) 
     ) 

이인데 스를 사용하는,하지만 난 reverseErtIndex 대신 인덱스를 강제하는 경우있는 key_len는 단 8 대신 원하는 19입니다 확장 프로그램 설명의 key_ln입니다 11

난 그냥 평등과 ERT 컬럼에 대해 비교를 교체하는 경우,있는 key_len는

(19)가 왜 MySQL은 전체 인덱스를 사용하지 않습니다입니까?

+0

때때로 mysql은 키를 무시하고 테이블 스캔을하는 것이 더 효율적이라고 결정할 것입니다. 어떤 경우 든 색인 생성이 다소 과장됩니다. 필드가 2 개 이상의 인덱스에 관련되어 있다면 별도로 인덱스하는 것이 더 나을 것입니다. –

+0

MySQL 5.5.15-log.USE를 FORCE로 바꾸어도 동작이 변경되지 않습니다. –

+0

나는 더 큰 데이터베이스에서 같은 것을 얻는다. 쿼리 계획은 ths 인덱스가 사용된다는 것을 보여줍니다. 듀얼 인덱스는 단지 처음 또는 마지막으로 테스트하기위한 것이므로 실제 DB에 모든 인덱스를 가지고 있지는 않습니다. 그러나 MySQL은 평등을 사용하는 열 또는 비교를 사용하는 열을 사용하지만 둘 다 사용하지는 않습니다. –

답변

0

11의 key_len (reverseErtIndex의 경우)은 JOIN 술어 (3 + 3 + 1 + 4)의 열에 해당합니다. 일치하는 행을 찾으려면 해당 열만 필요합니다. 아마도 EXPLAIN 결과는 MySQL이 ref 조인 작업 (type 열에 표시됨)을 사용하고 있음을 나타냅니다. 당신은 더 이상 EXPLAIN 출력에있는 key_len 수 있도록

쿼리를 수정

WHERE 절에 조건이 모두 평등 조건이라는 것을, 다음 ref 작업을 가입, 그래서는, 그 다른 컬럼에 확장 될 수 있습니다.

는 인덱스 컬럼에 불평등 비교를 들어, MySQL은은 ref 작업을 사용하지 않지만, 그것은 range 작업을 사용할 수 있습니다. MySQL은보다 긴 키 접두어에서 range 연산보다 짧은 키 접두어로 ref 연산을 선호합니다. MySQL의이 ertReverseIndex 인덱스를 사용하는 경우


, 우리는있는 key_len는 WHERE 절에 조건을 기준으로 range 작업, 팔 것으로 예상. ertFine 컬럼에서 술어를 제거한다면, EXPLAIN 출력에서 ​​key_len이 4로보고 될 것입니다.

MySQL이 다른 컬럼을 참조 (예 : "사용")하고 있는지 여부를 나타냅니다. 인덱스가 EXPLAIN 출력의 Extra 열에 "Using index"의 유무로 반영 될 것입니다. 그것이 존재한다면, 우리는 이것이 쿼리의 커버 인덱스이며, MySQL이 기본 테이블의 블록을 참조하지 않는다는 것을 알 수 있습니다.


하단에는 평등과 부등호 술어의 조합이 있습니다. MySQL은 ref (또는 equal_ref) 연산을 사용하여 같음 조건에 대해 연산을 수행하지만 불균형 조건에 대해서는 사용할 수 없습니다. 불평등의 경우, MySQL은 range 연산을 사용할 수 있습니다.

관련 문제