MySQL 데이터 테이블 인덱스 구축 방법

6704 단어 MySQL색인
색인 개념을 이해하는 가장 간단한 방법은 하나의 사례를 통해 진행되는 것이다. 다음은 바로 이런 사례이다.
만약에 우리가 온라인 데이트 사이트를 설계해야 한다고 가정하면 이 사이트의 사용자 자료는 국적, 성, 도시, 성별, 나이, 눈 색깔 등 여러 가지가 있다.이 사이트는 반드시 여러 가지 조합 방식을 통해 사용자 자료를 검색하는 것을 지원해야 한다.또한 정렬 지원과 사용자의 최근 온라인 시간과 다른 사용자의 평가에 따라 유한한 결과를 되돌려주는 것도 지원해야 한다.이런 복잡한 장면에 대해 우리는 어떻게 색인을 설계합니까?
좀 이상하다. 우선 우리가 색인 정렬을 사용해야 하는지, 검색한 후에 정렬을 해야 하는지 결정하는 것이다.색인 정렬은 색인과 조회 구축 방식을 제한합니다.예를 들어 WHERE age BETWEEN 18 AND 25와 같은 조회 조건과 다른 사용자 평가를 바탕으로 정렬된 장면에서 우리는 같은 색인을 사용할 수 없다.만약 MySQL이 범위 조회에서 색인을 사용했다면, 정렬에서 다른 색인을 사용할 수 없습니다.만약 이것이 가장 자주 사용하는 WHERE 조건이라고 가정한다면, 동시에 대부분의 조회를 정렬할 수 있도록 지원해야 한다.

다양한 유형의 필터링 지원


이제 어떤 열의 값이 비교적 분산되고 어떤 열이 WHERE 조건에서 가장 자주 나타나는지 살펴봐야 한다.데이터 열의 값이 비교적 분산된 선별성이 매우 좋다.이것은 보통 좋은 일이 될 것이다. 왜냐하면 이것은 MySQL이 관련되지 않은 데이터 줄을 효율적으로 필터할 수 있기 때문이다.
국적열은 선별성이 좋지 않을 수도 있지만 가장 자주 조회할 수도 있다.성별열은 통상적으로 선별성을 갖추지 못하지만, 검색에도 자주 사용된다.이러한 인식을 바탕으로 우리는 많은 다른 열의 조합을 위해 일련의 인덱스를 만들었습니다. 이 인덱스들은 (sex,country) 로 시작합니다.
전통적인 인지는 낮은 선별적인 열 구축 색인에 대해 쓸모가 없다.그러면 우리는 왜 모든 색인 시작에 선별되지 않은 열을 붙여야 합니까?우리는 이렇게 할 두 가지 이유가 있다.첫 번째 이유는 앞에서 말한 바와 같이 기본적으로 모든 조회에서 성별을 사용한다는 것이다.우리는 심지어 사용자가 한 번에 한 성별만 검색할 수 있도록 설계했다.그러나 더 중요한 것은 이런 열을 늘리는 것은 결점이 별로 없다. 왜냐하면 우리는 작은 수법을 사용했기 때문이다.
이것은 우리의 수법입니다. 성별 조회를 제한하지 않아도 WHERE 문장에 AND sex IN ('m','f') 을 추가하여 색인을 발효시킬 수 있습니다.이것은 우리가 필요로 하는 줄을 필터링하지 않기 때문에 WHERE 문장에 성별 작용을 포함하지 않는 것과 같다.그러나 MySQL은 더 많은 열의 인덱스에 이 열을 미리 설정하기 때문에 이 열을 포함해야 합니다.이 기법은 이런 장면에서 효과가 있지만 만약에 이 열이 많은 다른 값을 가지고 있다면 오히려 작용하지 않는다. 이것은 IN()의 열이 너무 많기 때문이다.
이 예는 데이터 테이블 디자인에 있어서 모든 옵션을 보존하는 기본적인 원칙을 논술했다.색인을 설계할 때, 그 검색 중의 그런 색인만 생각하지 말고, 동시에 검색 최적화를 고려해야 한다.색인이 필요하지만 다른 검색이 영향을 받을 수 있다는 것을 발견하면, 먼저 검색을 바꿀 수 있는지 물어봐야 한다.너는 쿼리와 색인을 동시에 최적화해서 해결책을 찾아야 한다.너는 반드시 완벽한 색인을 설계해야 하는 것은 아니다.
다음으로, 우리는 사용할 수 있는 다른 조합의 WHERE 조건을 고려한 다음, 그 중의 어떤 조합이 합리적인 인덱스가 없는 상황에서 느려질지 고려해야 한다.(sex,country,age) 같은 인덱스는 뚜렷한 선택이지만, 우리도 (sex,country,region,age) 와 (sex,country,region,city,age) 같은 인덱스가 필요할 수 있습니다.
이것은 많은 색인을 만들어야 하기 때문이다.만약 우리가 색인을 반복적으로 이용할 수 있다면, 너무 많은 조합이 생기지 않을 것이다.우리는 IN () 이라는 작은 수를 사용하여 (sex,country,age) 과 (sex,country,region,age) 인덱스를 제거할 수 있다.만약 이 열들이 검색 표에 지정되지 않았다면, 우리는 국가 명세서, 지역 명세서를 사용하여 색인 전치의 제약을 충족시킬 수 있다. (전체 국가, 모든 지역과 모든 성별의 조합이 많을 수 있다.)
이 색인들은 지정한 대부분의 검색 조회를 충족시킬 수 있지만, 사진 (has_pictures), 눈 색깔 (eye_color), 머리 색깔 (hair_color), 교육 수준 (education) 등 흔하지 않은 선별을 어떻게 설계합니까?만약 이 열들이 그렇게 선별적이고 자주 사용되지 않는다면, 우리는 직접 그들을 뛰어넘어 MySQL로 하여금 추가 데이터 줄을 스캔하게 할 수 있다.따라서 우리는age열 앞에서 그들을 추가하고 IN() 기교를 사용하여 이러한 열이 지정되지 않은 상황을 처리하도록 미리 설명할 수 있다.
우리가 색인 맨 뒤에 age를 놓았다는 것을 알아차렸을지도 모른다.왜 이 열을 특별히 처리해야 합니까?우리는 MySQL이 가능한 한 많은 색인 열을 사용할 수 있도록 보장하려고 노력하고 있다.첫 번째 범위 조회 조건이 발생할 때까지 MySQL에서 가장 왼쪽 일치 규칙을 사용합니다.우리가 언급한 모든 열은 WHERE 문장에서 같은 조건을 사용할 수 있지만, 나이(age)의 대략적인 확률은 범위 조회이다.
우리도 범위 조회를 명세서로 바꾸어 IN 조회를 사용할 수 있다. 예를 들어age IN(18, 19, 20, 21, 22, 23, 24, 25)을 사용하여age BETWEEN 18 AND 25를 대체할 수 있다. 그러나 이것은 항상 이렇게 할 수 있는 것은 아니다.통용되는 원칙은 우리가 가능한 한 범위 판결 조건을 색인의 끝에 두는 것이기 때문에 최적화기는 가능한 한 색인을 사용할 것이다.
우리는 WHERE 조건에서 지정되지 않은 색인 조건을 덮어쓰기 위해 가능한 한 많은 열을 사용할 수 있다고 언급했다.하지만 네가 지나치게 해서 새로운 문제를 초래했을 수도 있다.이런 IN 조회 목록을 더 많이 사용하면 최적화기가 대량의 조합을 평가해야 하기 때문에 오히려 조회 속도를 낮출 수 있다.다음 질의 조건 문구를 고려하십시오.

WHERE eye_color 	IN('brown', 'blue', 'hazel')
	AND hair_color	IN('black', 'red', 'blonde', 'brown')
  	AND sex 	IN('M', 'F')
이 최적화기는 432=24가지 조합으로 바뀌고 WHERE 조건은 모든 상황을 검사합니다.24는 아직 큰 조합 숫자는 아니지만 수량이 수천에 이르면이전 버전의 MySQL은 IN 조회 수가 너무 많을 때 더 많은 문제가 발생할 수 있습니다.검색 최적화기는 더 느리게 실행되고 많은 메모리를 소모합니다.새 버전의 MySQL은 조합이 너무 많을 때 평가를 중지하지만, 이것은 MySQL의 색인 사용에 영향을 줄 수 있습니다.

다중 범위 조회 방지


last_가 있다고 가정해 봅시다.온라인 (최근 온라인 시간) 의 열, 그리고 우리는 최근 일주일 동안 온라인 사용자를 보여야 한다.

WHERE eye_color		IN('brown', 'blue', 'hazel')
	AND hair_color	IN('black', 'red', 'blonde', 'brown')
  	AND sex 	IN('M', 'F')
 	AND last_online	 > DATE_SUB(NOW(), INTERVAL 7 DAY)
 	AND age		BETWEEN 18 AND 25 
이 조회의 문제는 두 가지 범위의 조회가 있다는 데 있다.MySQL은 last_온라인이나age 조건은 동시에 사용할 수 없습니다.하면, 만약, 만약...온라인 제약이 나타날 때age 제약이 없거나last_온라인은age보다 더 선별적입니다. 다른 색인을 추가해서last_온라인으로 맨 뒤에 놓으세요.그러나 만약에 우리가age를 IN 조회로 바꿀 수 없다면, 우리도last_가 동시에 있기를 바란다oinline과age범위 조회 시 조회 속도를 높이면 어떻게 합니까?이때 우리는 직접적인 방법이 없다.그러나 우리는 하나의 범위를 같은 비교로 바꿀 수 있다.이렇게 할 때, 우리는 미리 계산된 active 열을 추가합니다. 이 열은 정기적으로 유지보수됩니다.사용자가 로그인한 후 1을 표시하고 7일 동안 연속으로 로그인하지 않으면 0을 다시 표시합니다.
이 방법은 MySQL에서 (active, sex,country,age) 같은 인덱스를 사용할 수 있습니다.이 열은 그렇게 정확하지 않을 수도 있지만, 이런 조회는 아마도 매우 높은 정확도를 필요로 하지 않을 것이다.만약 우리가 정확한 조회를 필요로 한다면, 우리는 last_를 보류할 수 있다온라인은 WHERE 조건에 있지만 인덱스는 증가하지 않습니다.이 기술은 URL 찾기와 유사합니다.이 조건은 색인을 사용하지 않습니다. 왜냐하면 색인이 명중된 줄을 필터할 수 없기 때문입니다.색인을 늘리는 것이 반드시 조회 수익을 낼 수 있는 것은 아니다.
현재, 당신은 이 모드를 볼 수 있습니다. 만약 사용자가 활성화와 비활성화의 결과를 동시에 찾고 싶다면, 우리는 IN 조회를 사용할 수 있습니다.우리는 이러한 목록 조회를 많이 늘렸다. 하나의 변통적인 방식은 각 조합을 분리한 조회를 통해 단독으로 색인을 만드는 것이다. 예를 들어 우리는 다음과 같은 색인을 사용할 수 있다. (active,sex,country,age), (active,country,age), (sex,country,age), (country,age).이러한 인덱스는 특정한 조회에 더 좋은 선택이 될 수 있지만, 이러한 조합의 부정적인 효과를 유지하기 위해 조합에 필요한 추가 저장 공간은 매우 약한 전략을 초래할 수 있다.
이것은 최적화기가 바뀐 후에 색인 최적화에 진정으로 영향을 줄 수 있는 사례이다.만약 미래의 MySQL 버전에서 색인 스캔을 진정으로 버릴 수 있다면, 색인에 여러 범위의 조건을 사용할 수 있을 것이다. 이때 우리는 IN 조회를 통해 이런 문제를 해결할 필요가 없다.

정렬 최적화


마지막 의제는 순서다.작은 데이터 양의 결과는 파일 정렬 (filesort) 을 사용하면 빠르지만, 수백만 줄의 데이터라면?예를 들어, WHERE 조건에서만 성별이 지정된 경우 정렬됩니다.
이런 낮은 선별적인 장면에 대해 우리는 특정한 색인을 추가하여 정렬에 사용할 수 있다.예를 들어, 다음 질의에 사용할 수 있는 인덱스 (sex, rating) 가 있습니다.

SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 10;
이 검색은 정렬과 LIMIT 자구가 동시에 있어서 색인이 없는 상황에서 느릴 수 있습니다.색인이 있더라도 이 검색은 사용자 인터페이스에서 페이지별 검색이 있고, 페이지 번호가 시작 위치 근처에 없을 때도 느릴 수 있습니다.다음 예제에서는 ORDER BY와 LIMIT가 엉망인 조합을 만들었습니다.

SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000, 10;
설령 색인이 있다 하더라도 이런 조회는 매우 심각한 문제를 초래할 수 있다.높은 편이성 때문에 대량의 데이터를 스캔하는 데 많은 시간이 걸리고 버려지기 때문이다.반범식 설계로 미리 계산하고 캐시하면 이런 조회 문제를 해결할 수 있다.더 좋은 정책은 사용자가 조회할 수 있는 페이지 번호를 제한하는 것이다.10000페이지의 검색 결과에 관심을 갖는 사람은 사실상 없기 때문에 사용자의 체험을 떨어뜨릴 수 없다.
또 다른 좋은 전략은 추측 연합 조회를 사용하는 것이다. 이것은 우리가 덮어쓰기 인덱스를 이용하여 메인 키열을 얻은 후에 데이터 줄을 얻는 방식이다.가져와야 할 열을 모두 결합하면 MySQL이 버려야 할 데이터를 수집하는 작업을 줄일 수 있습니다.다음은 예입니다.

SELECT <cols> FROM profiles INNER JOIN (
  SELECT <primary key cols> FROM profiles
  WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
AS x USING(<primary key cols>);
다음은 MySQL이 데이터 테이블 인덱스를 어떻게 구축하는지에 대한 상세한 내용입니다. 더 많은 MySQL 데이터 테이블 인덱스 구축에 관한 자료는 저희 다른 관련 글을 주목해 주십시오!

좋은 웹페이지 즐겨찾기