programing

인덱스에서 열의 순서가 얼마나 중요합니까?

skycolor 2023. 4. 7. 21:05
반응형

인덱스에서 열의 순서가 얼마나 중요합니까?

지수 선언의 첫머리에 가장 선택적인 열을 넣어야 한다고 들었어요.예:

CREATE NONCLUSTERED INDEX MyINDX on Table1
(
   MostSelective,
   SecondMost,
   Least
)

일단 제 말이 맞나요?그렇다면 인덱스 내 열의 순서를 조정함으로써 성능 차이가 클 수 있습니까?아니면 '좋아요'에 가깝습니까?

DTA를 통해 쿼리를 실행한 후 기존 인덱스와 거의 모든 열이 동일한 인덱스를 다른 순서로 만들 것을 권장했기 때문입니다.기존 인덱스에 누락된 열을 추가하여 좋다고 부를까 생각 중입니다.생각?

다음과 같은 인덱스를 확인합니다.

Cols
  1   2   3
-------------
|   | 1 |   |
| A |---|   |
|   | 2 |   |
|---|---|   |
|   |   |   |
|   | 1 | 9 |
| B |   |   |
|   |---|   |
|   | 2 |   |
|   |---|   |
|   | 3 |   |
|---|---|   |

첫 번째 열을 사용하면 두 번째 열을 먼저 제한하는 것보다 더 많은 결과를 제거할 수 있으므로 A를 먼저 제한하는 방법을 알아보십시오.인덱스가 열 1, 열 2 등을 가로질러 이동하는 방법을 상상하면 더 쉽습니다.첫 번째 패스에서 대부분의 결과를 잘라내면 두 번째 단계가 훨씬 빨라집니다.

또 다른 경우, 3열에 문의하면 옵티마이저는 인덱스를 사용하지 않습니다.이는 결과 세트를 좁히는 데 전혀 도움이 되지 않기 때문입니다.문의가 있을 때마다 다음 단계 전에 처리할 결과 수를 줄이면 성능이 향상됩니다.

인덱스는 이 방법으로 저장되므로 인덱스를 쿼리할 때 첫 번째 열을 찾기 위해 인덱스를 역추적할 필요가 없습니다.

요컨대, 이것은 쇼가 아니라 실제 성능상의 이점이 있습니다.

열의 순서가 중요합니다.이제 어떤 순서가 올바른지 문의하는 방법에 따라 달라집니다.인덱스를 사용하여 정확한 탐색 또는 범위 스캔을 수행할 수 있습니다.정확한 검색은 인덱스의 모든 열에 대한 값이 지정되고 관심 행에 정확히 쿼리가 착지되는 경우입니다.포어범위 검색은 일부 열만 지정한 경우로, 이 경우 순서가 중요해집니다.SQL Server는 맨 왼쪽 열이 지정된 경우에만 범위 검색에 인덱스를 사용할 수 있으며 다음으로 왼쪽 열이 지정된 경우에만 범위 검색에 인덱스를 사용할 수 있습니다.에 인덱스가 있는 (A,B,C)에 대한 범위 할 수 .A=@a의 경우, 의 경우A=@a AND B=@b 위해서가 아니다B=@b의 경우, 의 경우C=@c 않다B=@b AND C=@c... ★★★★★★★★★★★★★★.A=@a AND C=@c입니다.A=@a는 인덱스를 만, 「인덱스는,C=@c B 않음)A=@a, 에, 에, 에, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,,C=@c다른 데이터베이스 시스템에는 외부 열이 지정되지 않은 경우 인덱스의 내부 열을 활용할 수 있는 이른바 '스킵 스캔' 연산자가 있습니다.

이 지식을 활용하면 인덱스 정의를 다시 볼 수 있습니다. on on 。(MostSelective, SecondMost, Least) 경우, 이 경우, 이 경우, 이 경우, 이 경우, 이 경우, 이 경우 이 효과가 있습니다.MostSelective컬럼이 지정됩니다.그러나 가장 선택적이기 때문에 내부 열의 관련성은 빠르게 저하됩니다.을 흔히 볼 수 .(MostSelective) include (SecondMost, Least) ★★★★★★★★★★★★★★★★★★.(MostSelective, SecondMost) include (Least)내부 컬럼은 관련성이 낮기 때문에 인덱스의 올바른 위치에 낮은 선택성 컬럼을 배치하면 탐색용 노이즈에 불과하므로 중간 페이지에서 이동시켜 리프 페이지에만 보관하는 것이 타당합니다. 인크루드(INCLUDE)로 ,, INCLUDE(인크루드)의 더 해집니다. 이것은 더 중요해진다.Least열이 증가합니다.가 도움이 될 수 것은, 이 인덱스가 유효하게 은, 이 인덱스가 유효하게 되다, 라고 하는 입니다.MostSelective정확한 값 또는 범위로 표시되며, 이 열은 가장 선택적이기 때문에 이미 후보 행을 상당히 제한합니다.

, 「」, 「」의 .(Least, SecondMost, MostSelective)실수처럼 보일지 모르지만, 사실 꽤 강력한 지표입니다. because the the the because the the the 、Least컬럼은 가장 바깥쪽 쿼리로 선택도가 낮은 컬럼에서 결과를 집계해야 하는 쿼리에 사용할 수 있습니다.이러한 쿼리는 OLAP 및 분석 데이터 웨어하우스에 널리 분포하고 있으며, 바로 이 점에서 이러한 인덱스가 매우 적합합니다.이러한 인덱스는 실제로 뛰어난 클러스터형 인덱스를 만듭니다.이것은, 관련하는 행의 큰 청크에 물리적인 레이아웃을 정리하기 때문입니다(동일).Least일반적으로 일종의 범주 또는 유형을 나타내며 분석 쿼리를 용이하게 합니다.

그래서 안타깝게도 '올바른' 순서는 없습니다.쿠키 커터 레시피를 따르지 말고 이러한 테이블에 대해 사용할 쿼리 패턴을 분석하여 올바른 인덱스 열 순서를 결정해야 합니다.

Remus가 말했듯이, 그것은 당신의 워크로드에 달려있다.

하지만 나는 받아들여진 답변의 오해를 불러일으키는 측면을 다루고 싶다.

인덱스의 모든 열에 대해 동등 검색을 수행하는 쿼리의 경우 큰 차이가 없습니다.

아래는 두 개의 테이블을 만들고 동일한 데이터로 채웁니다.유일한 차이점은 키가 가장 많은 것부터 가장 적은 것까지 정렬되어 있고 다른 하나는 그 반대라는 것입니다.

CREATE TABLE Table1(MostSelective char(800), SecondMost TINYINT, Least  CHAR(1), Filler CHAR(4000) null);
CREATE TABLE Table2(MostSelective char(800), SecondMost TINYINT, Least  CHAR(1), Filler CHAR(4000) null);

CREATE NONCLUSTERED INDEX MyINDX on Table1(MostSelective,SecondMost,Least);
CREATE NONCLUSTERED INDEX MyINDX2 on Table2(Least,SecondMost,MostSelective);

INSERT INTO Table1 (MostSelective, SecondMost, Least)
output inserted.* into Table2
SELECT TOP 26 REPLICATE(CHAR(number + 65),800), number/5, '~'
FROM master..spt_values
WHERE type = 'P' AND number >= 0
ORDER BY number;

이제 두 테이블을 모두 조회하는 중...

SELECT *
FROM   Table1
WHERE  MostSelective = REPLICATE('P', 800)
       AND SecondMost = 3
       AND Least = '~';

SELECT *
FROM   Table2
WHERE  MostSelective = REPLICATE('P', 800)
       AND SecondMost = 3
       AND Least = '~'; 

...둘 다 지수 과징금을 사용하고 둘 다 정확히 같은 비용이 부과됩니다.

여기에 이미지 설명 입력

승인된 답변의 ASCII 아트는 실제로 인덱스가 구성되는 방식이 아닙니다.표 1의 인덱스 페이지는 다음과 같습니다(풀사이즈로 열려면 이미지를 클릭하십시오).

여기에 이미지 설명 입력

인덱스 페이지에는 키 전체를 포함하는 행이 포함되어 있습니다(이 경우 인덱스가 고유하다고 선언되지 않았지만 무시해도 되는 추가 정보는 여기에서 확인할 수 있습니다).

위의 쿼리의 경우 SQL Server는 열의 선택성에 관심이 없습니다.루트 페이지의 바이너리 검색을 실시해, 키를 검출합니다. (PPP...,3,~ )>=(JJJ...,1,~ ) ★★★★★★★★★★★★★★★★★」< (SSS...,3,~ ) 이 .1:118그런 다음 해당 페이지의 키 엔트리를 바이너리 검색하여 아래로 이동할 리프 페이지를 찾습니다.

선택성의 순서로 인덱스를 변경해도 바이너리 검색에서 예상되는 키 비교 수나 인덱스 검색을 수행하기 위해 탐색해야 하는 페이지 수에는 영향을 주지 않습니다.기껏해야 키 비교 자체의 속도를 약간 높일 수 있습니다.

그러나 가장 선택적인 인덱스를 먼저 주문하는 것이 워크로드의 다른 쿼리에 도움이 될 수 있습니다.

예를 들어 워크로드에 다음 두 가지 형식의 쿼리가 모두 포함된 경우.

SELECT * ... WHERE  MostSelective = 'P'

SELECT * ...WHERE Least = '~'

위의 인덱스는 둘 다 커버하고 있지 않습니다. MostSelective 및 할 수 단, 에 대한 는 에 대한 것입니다.Least 않습니다

그러나 이 시나리오(종합지수의 선행 열의 하위 집합에 대한 지수 탐색을 포함하지 않음)는 지수에 의해 도움을 받을 수 있는 하나의 가능한 질의 클래스일 뿐이다. MostSelective 그 .MostSelective, SecondMost그리고 항상 세 개의 열을 모두 조합하여 검색하면 이 이론적인 이점은 쓸모가 없습니다.

반대로 다음과 같은 쿼리

SELECT MostSelective,
       SecondMost,
       Least
FROM   Table2
WHERE  Least = '~'
ORDER  BY SecondMost,
          MostSelective 

일반적으로 규정되어 있는 것과 역순서를 사용하는 것이 도움이 됩니다.쿼리를 커버하고 검색을 지원할 수 있으며 원하는 순서대로 행을 반환하여 부팅할 수 있습니다.

이는 반복적인 조언이지만 다른 쿼리에 대한 잠재적인 이점에 대한 경험적 접근일 뿐 실제로 워크로드를 검토하는 것을 대체할 수는 없습니다.

지수 선언의 시작 부분에 가장 선택적인 열을 넣어야 합니다.

맞아요.인덱스는 여러 열로 구성된 복합물이 될 수 있으며, 가장 왼쪽에 있는 원리 때문에 순서가 중요합니다.그 이유는 데이터베이스가 목록을 왼쪽에서 오른쪽으로 체크하고 정의된 순서에 일치하는 열 참조를 찾아야 하기 때문입니다.예를 들어, 주소 테이블에 열이 있는 인덱스가 있는 경우:

  • 주소.
  • 도시

를 사용한 임의의 address할 수 에 """만 에는 """이 사용됩니다.city "/"/"state참조 - 인덱스를 사용할 수 없습니다.맨 왼쪽 열이 참조되지 않기 때문입니다.쿼리 성능은 개별 인덱스 또는 순서가 다른 여러 복합 재료 중 어느 것이 가장 적합한지 알려 줍니다.좋은 읽기:킴벌리 트립의 티핑 포인트

선택성은 매우 작은 요소이며, "왼쪽 끝"은 매우 중요합니다.

순서를 선택할 때 합성 지수의 개별 열 선택성은 중요하지 않습니다.

여기 간단한 사고 과정이 있다: 효과적으로, 지수는 관련된 열의 연결이다.

이러한 근거를 제시하면 유일한 차이점은 문자열의 이전과 이후가 다른 두 개의 '스트링'을 비교하는 것입니다.이것은 총비용의 극히 일부입니다.하나의 답변에 언급된 "첫 번째 패스/두 번째 패스"는 없습니다.

그럼, 어떤 순서를 사용해야 할까요?

  1. =, 임의의 순서로.
  2. 그런 다음 하나의 범위 열에 고정합니다.

예를 들어, 여기서는 매우 낮은 선택 컬럼이 첫 번째가 되어야 합니다.

WHERE deleted = 0  AND  the_datetime > NOW() - INTERVAL 7 DAY
INDEX(deleted, the_datetime)

됩니다.deleted.

(열 정렬에는 더 많은 규칙이 있습니다.)

언급URL : https://stackoverflow.com/questions/2292662/how-important-is-the-order-of-columns-in-indexes

반응형