MySQL에서 두 개의 단일 열 인덱스 대 하나의 두 열 인덱스?


113

나는 다음과 같은 문제에 직면했고 모범 사례가 무엇인지 잘 모르겠습니다.

다음 테이블을 고려하십시오 (커질 것임).

id PK | giver_id FK | recipient_id FK | 데이트

나는 InnoDB를 사용하고 있으며 내가 이해하는 바에 따르면 두 개의 외래 키 열에 대한 인덱스가 자동으로 생성됩니다. 그러나 다음과 같은 특정 조합을 일치시켜야하는 많은 쿼리도 수행 할 것입니다.

SELECT...WHERE giver_id = x AND recipient_id = t.

이러한 각 조합은 테이블에서 고유합니다.

이 열에 대해 2 열 인덱스를 추가하면 어떤 이점이 있습니까? 아니면 이론상 두 개의 개별 인덱스가 충분하거나 동일합니까?


1
두 열의 조합이 고유 한 경우 쿼리 속도를 높일뿐만 아니라 테이블에 일관성을 추가하는 고유 한 기능이있는 2 열 인덱스를 만들 수 있습니다.
sguven

"MySQL은 인덱스의 모든 열을 테스트하는 쿼리 또는 첫 번째 열, 처음 2 개 열, 처음 3 개 열 등을 테스트하는 쿼리에 대해 다중 열 인덱스를 사용할 수 있습니다. 오른쪽에 열을 지정하면 색인 정의에서 단일 복합 색인은 동일한 테이블에서 여러 종류의 쿼리 속도를 높일 수 있습니다. " - 다중 열 인덱스
AlikElzin-kilaka

@ user1585784를 외삽하려면; 두 열의 조합이 고유 한 경우 고유 한 키를 사용해야한다고 생각합니다. 사실, 데이터베이스 수준에서 고유성을 적용하려는 경우 고유 키가 가장 쉬운 방법입니다.
Erk

답변:


132

두 개의 단일 열 인덱스가있는 경우이 중 하나만 예제에서 사용됩니다.

두 개의 열이있는 인덱스가있는 경우 쿼리가 더 빠를 수 있습니다 (측정해야 함). 두 열 인덱스는 단일 열 인덱스로도 사용할 수 있지만 처음에 나열된 열에 만 사용할 수 있습니다.

때로는 (A, B)에 대한 인덱스와 (B)에 대한 다른 인덱스를 갖는 것이 유용 할 수 있습니다. 이렇게하면 열 중 하나 또는 둘 모두를 사용하는 쿼리가 빨라지지만 물론 더 많은 디스크 공간을 사용합니다.

인덱스를 선택할 때 삽입, 삭제 및 업데이트에 대한 영향도 고려해야합니다. 더 많은 인덱스 = 느린 업데이트.


1
"MySQL은 인덱스의 모든 열을 테스트하는 쿼리 또는 첫 번째 열, 처음 2 개 열, 처음 3 개 열 등을 테스트하는 쿼리에 대해 다중 열 인덱스를 사용할 수 있습니다. 오른쪽에 열을 지정하면 색인 정의에서 단일 복합 색인은 동일한 테이블에서 여러 종류의 쿼리 속도를 높일 수 있습니다. " - 다중 열 인덱스
AlikElzin-kilaka

33

다음과 같은 커버링 인덱스 :

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

... 쿼리가 언급 된 경우 인덱스가 사용될 수 있다는 것을 의미 giver_id, 또는 조합 giver_idrecipient_id. 인덱스 기준은 맨 왼쪽에 기반한다는 점에 유의하십시오.를 참조하는 쿼리 recipient_id는 내가 제공 한 명령문에서 포함 인덱스를 사용할 수 없습니다.

또한 MySQL은 SELECT 당 하나의 인덱스 만 사용할 수 있으므로 커버링 인덱스가 쿼리를 최적화하는 가장 좋은 방법입니다.


10
MySQL can only use one index per SELECT이것은 더 이상 사실이 아닙니다. 답변을 업데이트하도록 편집하면 좋을 것입니다.
Davor

에서 커버링 인덱스를 사용할 수없는 이유를 설명해 주시겠습니까 recipient_id?
Ivo Pereira 2015 년

2
@IvoPereira MySQL의 다중 열 인덱스를 사용하면 인덱스의 모든 필드를 왼쪽에서 오른쪽으로 사용할 수 있습니다. 예를 들어, 당신은이 경우 INDEX (col1, col2, col3, col4)다음 인덱스가 함께 검색에 적용 할 것 WHERE같은 절 col1 = 'A'또는 col1 = 'A' AND col2 = 'B'또는 col1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'하지만,이 특정 인덱스는 같은 것을 사용하지 않을 WHERE col2 = 'B'또는 WHERE col3 = 'C' AND col4 = 'D'검색 필드는 인덱스 정의에서 가장 왼쪽되지 않기 때문에. 이러한 필드를 포함하려면 추가 색인을 추가해야합니다.
Slicktrick

"SELECT 당 하나의 인덱스" , 이것이 mariadb 10.1에서도 여전히 사실입니까?
oldboy

1
@Anthony : 아니요. 위의 Davor의 의견을 참조하십시오.
kapad

4

외래 키 인덱스 중 하나가 이미 매우 선택적인 경우 데이터베이스 엔진은 지정한 쿼리에 해당 인덱스를 사용해야합니다. 대부분의 데이터베이스 엔진은 이러한 상황에서 최적의 인덱스를 선택할 수 있도록 일종의 휴리스틱을 사용합니다. 어느 인덱스도 그 자체로 선택성이 높지 않은 경우, 해당 유형의 쿼리를 많이 사용할 것이라고 말 했으므로 두 키에 빌드 된 인덱스를 추가하는 것이 좋습니다.

이 테이블의 PK 필드를 제거하고에 기본 키 인덱스를 정의 할 수 있는지 고려해야 할 또 다른 것입니다 giver_idrecipient_id필드. 당신은 조합이 독특하기 때문에 아마도 효과가있을 것이라고 말했습니다 (당신 만이 대답 할 수있는 다른 많은 조건을 감안할 때). 그러나 일반적으로 추가되는 복잡성은 번거로울 가치가 없다고 생각합니다.


감사합니다 Mark, 키 중 하나는 실제로 매우 선택적이므로 괜찮을 것입니다. 나는 두 개의 (자동) 인덱스를 제자리에 유지하고 시간이 지남에 따라 어떻게 작동하는지 확인하기로 결정했습니다. 나는 또한 결합 된 giver : recipient 기본 키에 대해 생각했지만 각 필드도 개별적으로 검색 할 수 있어야하므로 PHP 오버 헤드 만 추가됩니다. 또한 새 키는 (짧은) 정수 대신 (긴) 문자열이됩니다.

2

고려해야 할 또 다른 사항은 두 접근 방식의 성능 특성이 데이터 세트의 크기와 카디널리티를 기반으로한다는 것입니다. 2 열 인덱스는 특정 데이터 세트 크기 임계 값 또는 정반대의 경우에만 성능이 향상된다는 것을 알 수 있습니다. 정확한 시나리오에 대한 성능 메트릭을 대체 할 수있는 것은 없습니다.


이에 대한 문서를 링크 해 주시겠습니까? 감사.
kapad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.