2009-08-09 6 views
29

이것은 영원히 가지고있는 질문입니다.MySQL 인덱스 및 순서

인덱스의 순서가 중요하다는 것을 알고있는 한. 따라서 [first_name, last_name]과 같은 색인은 [last_name, first_name]과 같지 않습니까? 나는 첫 번째 인덱스를 정의하면

, 그것은 단지

SELECT * FROM table WHERE first_name="john" AND last_name="doe"; 

사용하고 있지 내가 ORM을 사용하고 있기 때문에

SELECT * FROM table WHERE last_name="doe" AND first_name="john"; 

, 나는 아무 생각에서이 없다는 것을 의미 하는가 이 열들은 순서대로 호출됩니다. 모든 순열에 인덱스를 추가해야한다는 의미입니까? 2 열 인덱스가 있으면 그렇게 할 수 있지만 인덱스가 3 열 또는 4 열이면 어떻게됩니까?

답변

44

색인 조건은 검색어 조건이 색인의 경우에만에만 적용되는 경우에 중요합니다. 고려 : 1 질의 색인 인 경우

  1. SELECT * FROM table WHERE first_name="john" AND last_name="doe"

  2. SELECT * FROM table WHERE first_name="john"

  3. SELECT * FROM table WHERE last_name="doe"

(first_name, last_name을)과 (2)를 사용, 쿼리 # 삼원 '티. 색인이 (last_name, first_name) 인 경우 1과 3의 검색어가 사용되며 2 번째의 검색어는 사용되지 않습니다. WHERE 절 내의 조건 순서 변경은 두 경우 모두 적용되지 않습니다.

내역은 다음과 같습니다 here

업데이트 : 경우
위 명확하지 않다 - 쿼리 조건의 열 인덱스의 왼쪽 접두사를 형성하는 경우 MySQL은 오직 인덱스를 사용할 수 있습니다. 위 쿼리 # 2는 first_name만을 기반으로하고 first_name은 (last_name, first_name) 색인의 가장 앞에있는 접두사가 아니기 때문에 (last_name, first_name) 색인을 사용할 수 없습니다.

쿼리 내에서 조건의 순서는 중요하지 않습니다. 위의 쿼리 # 1은 조건이 first_namelast_name이므로 합계로 (last_name, first_name) 색인을 사용할 수 있으며 함께 사용하면 (last_name, first_name) 색인의 가장 왼쪽 접두사가됩니다.

+0

그래서 추측 * 테이블에서 where last_name = "doe"AND first_name = "john"은 아닐까요? 그렇다면 모든 쿼리 건물이 내 ORM에 의해 숨겨져 있기 때문에 정의 할 3 열의 인덱스가 있기 때문에 아마도 2 인덱스를 정의해야합니다 ... 정말 싫은데 ... –

+1

아니요, 너 오해 했어. 'last_name' = "doe"AND'first_name' = "john"질의는 ('first_name','last_name') 또는 ('last_name','first_name') 인덱스를 사용합니다. – ChssPly76

+0

질문 : 2 AND 조건을 가진 쿼리의 경우 쿼리의 조건과 비교하여 인덱스가 "반전"되었습니까? 아니면 해당 열의 카디널리티에 따라 달라질까요? – Mihai

5

ChssPly76은 부울 식의 순서가 색인의 열 순서와 일치하지 않아도되는 것이 정확합니다. 부울 연산자는 commutative이며, 대부분의 경우 식과 색인을 일치시키는 방법을 알기에 MySQL 옵티마이 저는 충분히 똑똑합니다.

또한 MySQL의 EXPLAIN 기능을 사용하는 방법을 배워야하므로 옵티마이 저가 주어진 쿼리에 대해 선택할 인덱스를 직접 확인할 수 있습니다.

+2

+1 설명. – Petrogad

+0

MySQL Workbench는 Execution Plan 아래에있는'EXPLAIN' 정보를 그래픽으로 보여줍니다. –

2

왜 모든 것을 한 번에 완전하게 수정하려면 대답을 조금만 확장하지 않는 것이 좋을까요?

테이블에 다중 열 인덱스가있는 경우 인덱스의 가장 왼쪽에있는 접두사를 사용하여 옵티마이 저가 행을 찾을 수 있습니다. 예를 들어 (col1, col2, col3)에 3 열 인덱스가있는 경우 (col1), (col1, col2)(col1, col2, col3)에 대한 검색 기능 색인이 생성됩니다.

인덱스가 인덱스의 맨 앞자리를 차지하지 않으면 MySQL은 인덱스를 사용할 수 없습니다. 당신이 여기에 표시된 SELECT 문을 가지고 있다고 가정하자 : 인덱스가 (col1, col2, col3)에 존재

SELECT * FROM tbl_name WHERE col1=val1; 
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2; 

SELECT * FROM tbl_name WHERE col2=val2; 
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3; 

경우 첫 번째 두 쿼리가 인덱스를 사용합니다. 세 번째와 네 번째 쿼리에는 인덱싱 된 열이 포함되지만 (col2)(col2, col3)은 가장 왼쪽의 접두사가 아니며 (col1, col2, col3)입니다. - MySQL dev