13.2.9.3 인덱스 힌트 구문
쿼리 처리 중에 인덱스를 선택하는 방법에 대한 정보를 최적화에 제공하기위한 팁을 지정할 수 있습니다. 섹션 13.2.9.2 "JOIN" 는 SELECT
문에서 테이블을 지정하기위한 일반적인 구문에 대해 설명하고 있습니다. 개별 테이블의 구문 (인덱스 힌트 구문을 포함)은 다음과 같이됩니다.
tbl_name
[AS]alias
] [index_hint_list
]index_hint_list
:index_hint
[,index_hint
] ...index_hint
: USE {INDEX | KEY} [FOR {JOIN | ORDER BY | GROUP BY} ([index_list
) | IGNORE {INDEX | KEY} [FOR {JOIN | ORDER BY | GROUP BY} (index_list
) | FORCE {INDEX | KEY} [FOR {JOIN | ORDER BY | GROUP BY} (index_list
)index_list
:index_name
[,index_name
] ...
USE INDEX (
을 지정하여 테이블의 행을 검색하기 위해 지정된 인덱스 하나만 사용하도록 MySQL에 지시 할 수 있습니다. 대신 구문 index_list
)IGNORE INDEX (
를 사용하면 어떤 특정 (하나 이상의) 인덱스를 사용하지 않게 MySQL에 지시 할 수 있습니다. 이 팁은 index_list
)EXPLAIN
하여 MySQL이 가능한 인덱스 목록에서 잘못된 인덱스를 사용하는 것으로 나타하면 도움이됩니다.
또한 USE INDEX (
와 같은 기능을 가지지 만, 테이블 스캔이 매우 부하가 크다고 보여지는 점이 추가 된 index_list
)FORCE INDEX
를 사용할 수 있습니다. 즉, 테이블 스캔은 지정된 인덱스 중 하나를 사용하여 테이블에서 행을 검색하는 방법이없는 경우에만 사용됩니다.
각 팁에는 컬럼의 이름이 아니라 인덱스의 이름이 필요합니다. PRIMARY KEY
이름은 PRIMARY
입니다. 테이블의 인덱스 이름을 표시하려면 SHOW INDEX
를 사용합니다.
index_name
값은 전체 인덱스 이름 일 필요는 없습니다. 인덱스 이름의 애매하지 않은 프리픽스 할 수 있습니다. 프리픽스가 모호한 경우 오류가 발생합니다.
예 :
SELECT * FROM table1 USE INDEX (col1_index, col2_index) WHERE col1 = 1 AND col2 = 2 AND col3 = 3; SELECT * FROM table1 IGNORE INDEX (col3_index) WHERE col1 = 1 AND col2 = 2 AND col3 = 3;
인덱스 힌트 구문에는 다음과 같은 특징이 있습니다.
USE INDEX
빈index_list
을 지정하는 (즉, "인덱스를 사용하지 않는") 것은 구문으로 유효합니다.FORCE INDEX
또는IGNORE INDEX
빈index_list
을 지정할 구문 오류입니다.팁
FOR
절을 추가하여 인덱스 힌트 범위를 지정할 수 있습니다. 이로 인해 쿼리 처리의 다양한 단계에 대한 최적화 실행 계획의 선택을보다 세밀하게 제어 할 수 있습니다. MySQL이 테이블의 행의 검색 방법과 결합의 처리 방법을 결정하는 데 사용되는 인덱스에만 영향을주고,FOR JOIN
을 사용합니다. 행을 정렬하거나 그룹화하기위한 인덱스 사용에 영향을주고,FOR ORDER BY
또는FOR GROUP BY
를 사용합니다. (단, 테이블을 범위에 포함 인덱스가 존재하고 그것이 테이블에 액세스하는 데 사용되는 경우 옵티마이 저는 인덱스를 비활성화IGNORE INDEX FOR {ORDER BY|GROUP BY}
힌트를 무시합니다 .)여러 인덱스 힌트를 지정할 수 있습니다.
SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;
여러 팁 같은 인덱스를 지정하는 것은 (같은 팁 내라도) 오류가 없습니다.
SELECT * FROM t1 USE INDEX (i1) USE INDEX (i1, i1);
그러나 동일한 테이블에 대해
USE INDEX
와FORCE INDEX
를 혼합하면 오류가 발생합니다.SELECT * FROM t1 USE INDEX FOR JOIN (i1) FORCE INDEX FOR JOIN (i2);
인덱스 힌트에서 FOR
절을 지정하지 않으면 기본적으로 그 팁 문의 모든 부분에 적용됩니다. 예를 들어, 다음의 팁
IGNORE INDEX (i1)
다음 팁의 조합과 동일합니다.
IGNORE INDEX FOR JOIN (i1) IGNORE INDEX FOR ORDER BY (i1) IGNORE INDEX FOR GROUP BY (i1)
서버에서 FOR
절이 존재하지 않을 때 (팁이 행의 취득에만 적용되도록) 팁 범위에 대한 이전 동작이 사용되도록하려면 서버를 시작할 때 이전
시스템 변수를 사용합니다 . 복제 설정에서이 변수를 사용하는 경우주의하십시오. 명령문 기반 바이너리 로깅에서 마스터와 슬레이브에 서로 다른 모드를 사용하면 복제 오류가 발생할 수 있습니다.
인덱스 힌트가 처리 될 때 이러한 인덱스 힌트는 형태 ( USE
, FORCE
, IGNORE
) 및 범위 ( FOR JOIN
, FOR ORDER BY
, FOR GROUP BY
)마다 하나의 목록으로 수집됩니다. 예 :
SELECT * FROM t1 USE INDEX () IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2);
다음과 같습니다.
SELECT * FROM t1 USE INDEX (i1, i2) IGNORE INDEX (i2);
그 후, 인덱스 힌트는 범위마다 다음 순서로 적용됩니다.
{USE|FORCE} INDEX
가 존재하는 경우에는 이것이 적용됩니다. (존재하지 않는 경우는 최적화에 의해 결정되는 인덱스 세트가 사용됩니다.)이전 단계의 결과에 대해
IGNORE INDEX
가 적용됩니다. 예를 들어, 다음 두 쿼리는 동일합니다.SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX (i2) USE INDEX (i2); SELECT * FROM t1 USE INDEX (i1);
FULLTEXT
검색하면 인덱스 힌트는 다음과 같이 작동합니다.
자연 언어 모드 검색의 경우 인덱스 힌트는 암묵적으로 무시됩니다. 예를 들어,
IGNORE INDEX(i)
는 경고없이 무시되어 인덱스가 계속 사용됩니다.boolean 모드 검색의 경우
FOR ORDER BY
또는FOR GROUP BY
를 포함 인덱스 힌트는 암묵적으로 무시됩니다.FOR JOIN
을 포함한 인덱스 힌트 또는FOR
수식을 포함하지 않는 인덱스 힌트는 허용됩니다. 팁FULLTEXT
이외의 검색에 적용되는 경우와는 달리,이 힌트는 쿼리 실행의 모든 단계 (행의 검색 및 검색, 그룹화 및 순서화)에 사용됩니다. 이것은 힌트가FULLTEXT
이외의 인덱스에 대해 지정된 경우에도 마찬가지입니다.
예를 들어, 다음 두 쿼리는 동일합니다.
SELECT * FROM t USE INDEX (index1) IGNORE INDEX (index1) FOR ORDER BY IGNORE INDEX (index1) FOR GROUP BY WHERE ... IN BOOLEAN MODE ...; SELECT * FROM t USE INDEX (index1) WHERE ... IN BOOLEAN MODE ...;