2013-08-10 1 views
4

대신 인덱스의 기본 키를 사용MySQL은 내가 몇 백만 행이 꽤 큰 테이블이

SELECT id, countrycode, status, flag_cc FROM table WHERE ID>=200000 AND countrycode=3 AND status=1 AND flag_cc=0 

그래서 : 나는 다음과 같은 SQL 문을 시도했지만 그것은 아주 느렸다

ID (primary) 
countrycode 
status 
flag_cc 

ADD INDEX myindex(id, countrycode, status, flag_cc) 

가 그럼 난 조회 : 나는 그 쿼리를 고정하기 위해 인덱스를 추가하는 것은 좋은 생각 일 것이다라고 생각했다

EXPLAIN SELECT id, countrycode, status, flag_cc FROM table WHERE ID>=200000 AND countrycode=3 AND status=1 AND flag_cc=0 

하지만 mysql은 내 키 대신 기본 키를 사용하려고합니다. 그래서 FORCE INDEX를 사용하여 기본 키를 내 키와 비교했습니다. 슬프게도 기본 키는 훨씬 빠릅니다.

어떻게 될 수 있습니까? 기본 키가 너무 느린 경우에도 쿼리를 최적화 할 수 있습니까?

+0

시도는 키 primay 3 별도의 키없이 복합 키를 추가. –

+0

기본 키가없는 compund key를 추가하면 기본 키가 여전히 사용됩니다. – Gio

+1

색인 (countrycode, status, flag_cc, id)을이 순서대로 사용해보십시오. 상수를 먼저 찾을 때 더 빠를 수도 있습니다. – noz

답변

3

기본적으로 "좋은 색인은 무엇입니까?" MySQL 문서, 여기 stackoverflow 및 모든 검색 엔진을 사용하여 해당 항목을 읽는 것이 좋습니다.

큰 백과 사전의 색인과 같은 색인을 고려하십시오. 정의 된 항목이 많기 때문에 색인을 통해 원하는 것을 빠르게 찾을 수 있습니다.

하지만 색인에 무엇이 있어야합니까? 카테고리 (과학, 엔터테인먼트, 사람, ...)? 카테고리를 찾았을 때 각 카테고리에 속하는 기사는 여전히 많이 있습니다. 과학 카테고리에 1000 개가 넘는 기사가 10,000 개 있다고합시다. 당신이 science-ey 무언가를 찾는 경우에, 그것은 당신의 정확한 기사를 처음부터 끝까지 볼 것이다 1000의 기사로 당신을 넣어 둡니다. 데이터베이스 측면에서 보면이 인덱스는 좋은 카디널리티을 가지고 있지 않습니다. 그 밖의 것은 없지만 충분히 구체화되지 않은 경우 의 속도가 빨라지면 좋습니다. 동일은 (그래서 또한 매우 구체적인하지 않은, 대략 26를 찾기 위해 당신이 기사의 수를 분할 인덱스를 사용하여 알파벳 26 글자) 편지를 시작하여 인덱스에 대한 유지한다.

데이터베이스에서 이것은 기본 키가 색인 할 수있는 아주 좋은 필드라는 것을 의미합니다.이 필드의 값 하나는 데이터의 정확히 하나의 값과 일치하므로 색인을 사용하여 찾으면 아무 것도 볼 수 없습니다 ; 이미 특정 레코드를 찾았습니다.

반면에, 참/거짓 깃발 만 여전히 인덱스를 사용 후에도 통해보고 데이터를 많이 잎 그래서, 두 그룹의 최대에 데이터를 나눕니다.

물론 예외가 있습니다. 예를 들어, true/false 열이있는 테이블. 일반적으로 이것은 인덱스하기에 좋지 않은 컬럼입니다. 그러나 아마도 모든 레코드의 0.01 %만이 해당 열에 대해 'true'값을 가지며 쿼리가 true 값을, 결코 false 값을 찾습니다. 이 경우 true/false 열은 색인 할 좋은 열입니다.

범위 문제가 있습니다. 특정 ID가 아닌 전체 범위를 검색하므로 ID가 고유하더라도 색인의 전체 섹션 (즉 데이터)를 '색인을 사용한 후에도 계속 살펴볼'것으로 정의합니다. 그것은 좋은 카디있는 동안, 그것은하지 않을 수 있도록 최선의 색인이 특정 쿼리에 대해 사용할 수 있습니다.

또 다른 문제점은 인덱스의 첫 번째 열을 검색하지 않을 때 MySQL이 다중 열 인덱스를 조사 할 수 없다는 것입니다. 따라서 인덱스 (ID, 국가 코드, 상태, 플래그 _cc)는 MySQL이 ID로 색인을 사용하기 시작해야한다는 것을 의미합니다.이 쿼리는 범위 조건이며 이전 단락은 왜 그 것이 나쁜지를 설명합니다. 인덱스의 ID 부분을 적용한 후에 만 ​​countrycode 부분으로 시작할 수 있습니다. MySQL이 여전히 노력할만한 가치가 있다고 판단한 경우입니다. 이것은 아마도 MySQL이 당신이 다른 옵션을 주더라도 기본 키 인덱스를 사용하고자하는 이유 일 것입니다.

테이블에이 모든 정보를 적용합니다. where 절에 모든 열이 포함되므로 가장 높은 카디널리티 (가장 다른 값)를 가진 열로 시작하고 where 절에 대한 인덱스로 사용되는 인덱스를 작성하십시오 not ID). flag_cc에 많은 값이 포함되어 있다면이를 사용하십시오. status 또는 countrycode에 더 많은 값이 포함되어있는 경우 그 중 하나를 사용하십시오. 색인을 생성하는 첫 번째 열의 구체적인 방법에 따라 단일 열을 색인하는 것으로 충분할 수 있습니다. 그렇지 않은 경우 인덱스에 차선책 인 카디널리티가 추가 된 열을 추가해보십시오.

물론 인덱스 (일반적으로 항상 그런 것은 아님)가 조회 속도를 높이지만 업데이트, 삽입 및 삭제 속도가 느려지는 것을 기억하십시오!

매우 단순한 문제는 아닙니다. 또한 제가 설명한 것들이 색인 얼음 빙산의 일각에 지나지 않는다고 생각하십시오.

출처 :

http://webmonkeyuk.wordpress.com/2010/09/27/what-makes-a-good-mysql-index-part-2-cardinality/ https://dev.mysql.com/doc/refman/5.6/en/multiple-column-indexes.html

관련 문제