SQL의 인덱스란 무엇입니까? SQL - 인덱스. SQL Server에서 클러스터형 인덱스와 비클러스터형 인덱스를 B-Tree라고 부르는 이유는 무엇입니까?

달성하는 가장 중요한 방법 중 하나 고성능 SQL 서버 인덱스를 사용하는 것입니다. 인덱스는 다음을 제공하여 쿼리 프로세스 속도를 높입니다. 빠른 액세스책의 색인과 마찬가지로 테이블의 데이터 행에 추가하면 필요한 정보를 빠르게 찾을 수 있습니다. 이 기사에서 나는 줄 것이다 짧은 리뷰인덱스 SQL 서버데이터베이스에서 구성되는 방식과 데이터베이스 쿼리 속도를 높이는 데 어떻게 도움이 되는지 설명합니다.

인덱스는 테이블 및 뷰 열에 생성됩니다. 인덱스는 해당 열의 값을 기반으로 데이터를 빠르게 검색하는 방법을 제공합니다. 예를 들어 기본 키에 대한 인덱스를 생성한 다음 기본 키 값을 사용하여 데이터 행을 검색하는 경우 SQL 서버먼저 인덱스 값을 찾은 다음 인덱스를 사용하여 전체 데이터 행을 빠르게 찾습니다. 인덱스가 없으면 테이블의 모든 행에 대한 전체 스캔이 수행되며 이는 성능에 상당한 영향을 미칠 수 있습니다.
테이블이나 뷰의 대부분의 열에 인덱스를 만들 수 있습니다. 예외는 주로 대형 객체를 저장하기 위한 데이터 유형이 있는 열입니다( 맥없이 걷다), 와 같은 영상, 텍스트또는 varchar(최대). 형식으로 데이터를 저장하도록 설계된 열에 인덱스를 만들 수도 있습니다. XML, 그러나 이러한 인덱스는 표준 인덱스와 약간 다르게 구성되어 있으며 이에 대한 고려 사항은 이 기사의 범위를 벗어납니다. 또한 기사에서는 논의되지 않습니다. 기둥 저장소인덱스. 대신 데이터베이스에서 가장 일반적으로 사용되는 인덱스에 중점을 둡니다. SQL 서버.
인덱스는 트리 구조로 구성된 페이지 집합, 인덱스 노드로 구성됩니다. 균형 잡힌 나무. 이 구조는 본질적으로 계층적이며 그림과 같이 계층 구조의 맨 위에 있는 루트 노드와 맨 아래에 있는 리프 노드로 시작합니다.


인덱싱된 열을 쿼리하면 쿼리 엔진은 루트 노드의 맨 위에서 시작하여 중간 노드를 통해 아래로 작동하며 각 중간 계층에는 데이터에 대한 더 자세한 정보가 포함됩니다. 쿼리 엔진은 인덱스 리프가 있는 최하위 수준에 도달할 때까지 인덱스 노드를 계속 이동합니다. 예를 들어, 인덱싱된 열에서 값 123을 찾는 경우 쿼리 엔진은 먼저 루트 수준의 첫 번째 중간 수준에 있는 페이지를 결정합니다. 이 경우 첫 번째 페이지는 1부터 100까지의 값을 가리키고 두 번째 페이지는 101부터 200까지의 값을 가리키므로 쿼리 엔진은 이 중간 수준의 두 번째 페이지에 액세스하게 됩니다. 다음으로 다음 중급 레벨의 세 번째 페이지로 넘어가야 한다는 것을 알게 될 것입니다. 여기에서 쿼리 하위 시스템은 더 낮은 수준에서 인덱스 자체의 값을 읽습니다. 인덱스 리프에는 인덱스 유형(클러스터형 인덱스 또는 비클러스터형 인덱스)에 따라 테이블 데이터 자체 또는 테이블에 데이터가 있는 행에 대한 포인터만 포함될 수 있습니다.

클러스터형 인덱스
클러스터형 인덱스는 인덱스의 리프에 실제 데이터 행을 저장합니다. 이전 예제로 돌아가면 이는 키 값 123과 연결된 데이터 행이 인덱스 자체에 저장된다는 의미입니다. 중요한 특성클러스터형 인덱스는 모든 값이 오름차순 또는 내림차순으로 특정 순서로 정렬되는 것입니다. 따라서 테이블이나 뷰에는 클러스터형 인덱스가 하나만 있을 수 있습니다. 또한 테이블의 데이터는 해당 테이블에 클러스터형 인덱스가 생성된 경우에만 정렬된 형태로 저장된다는 점에 유의해야 합니다.
클러스터형 인덱스가 없는 테이블을 힙이라고 합니다.
비클러스터형 인덱스
클러스터형 인덱스와 달리 비클러스터형 인덱스의 리프에는 해당 열( 열쇠) 이 인덱스가 결정되며 테이블의 실제 데이터가 있는 행에 대한 포인터도 포함됩니다. 이는 하위 쿼리 시스템이 필요한 데이터를 찾고 검색하기 위해 추가 작업이 필요함을 의미합니다. 데이터 포인터의 내용은 데이터가 저장되는 방식(클러스터링된 테이블 또는 힙)에 따라 달라집니다. 포인터가 클러스터형 테이블을 가리키는 경우 실제 데이터를 찾는 데 사용할 수 있는 클러스터형 인덱스를 가리킵니다. 포인터가 힙을 참조하는 경우 특정 데이터 행 식별자를 가리킵니다. 비클러스터형 인덱스는 클러스터형 인덱스처럼 정렬할 수 없지만 테이블이나 뷰에 하나 이상의 비클러스터형 인덱스(최대 999개)를 생성할 수 있습니다. 그렇다고 해서 인덱스를 최대한 많이 생성해야 한다는 의미는 아닙니다. 인덱스는 시스템 성능을 향상시키거나 저하시킬 수 있습니다. 여러 개의 비클러스터형 인덱스를 생성할 수 있을 뿐만 아니라 추가 열( 포함된 열)을 인덱스에 추가합니다. 인덱스의 리프에는 인덱스된 열 자체의 값뿐만 아니라 인덱스되지 않은 추가 열의 값도 저장됩니다. 이 접근 방식을 사용하면 인덱스에 적용되는 일부 제한 사항을 우회할 수 있습니다. 예를 들어 인덱싱할 수 없는 열을 포함하거나 인덱스 길이 제한(대부분의 경우 900바이트)을 우회할 수 있습니다.

인덱스 유형

클러스터형 인덱스 또는 비클러스터형 인덱스 외에도 복합 인덱스, 고유 인덱스 또는 포함 인덱스로 추가로 구성할 수 있습니다.
종합지수
이러한 인덱스에는 둘 이상의 열이 포함될 수 있습니다. 인덱스에는 최대 16개의 열을 포함할 수 있지만 총 길이는 900바이트로 제한됩니다. 클러스터형 인덱스와 비클러스터형 인덱스는 모두 복합형 인덱스일 수 있습니다.
고유 인덱스
이 인덱스는 인덱싱된 열의 각 값이 고유하도록 보장합니다. 인덱스가 복합 인덱스인 경우 고유성은 인덱스의 모든 열에 적용되지만 각 개별 열에는 적용되지 않습니다. 예를 들어, 열에 고유 인덱스를 생성하는 경우 이름그리고 , 저것 성명고유해야 하지만 이름이나 성은 중복될 수 있습니다.
열 제약 조건(기본 키 또는 고유 값 제약 조건)을 정의하면 고유 인덱스가 자동으로 생성됩니다.
  • 기본 키
    하나 이상의 열에 기본 키 제약 조건을 정의하면 SQL 서버이전에 클러스터형 인덱스가 생성되지 않은 경우 고유한 클러스터형 인덱스가 자동으로 생성됩니다(이 경우 기본 키에 고유한 비클러스터형 인덱스가 생성됨)
  • 가치의 고유성
    값의 고유성에 대한 제약 조건을 정의하면 SQL 서버고유한 비클러스터형 인덱스를 자동으로 생성합니다. 테이블에 클러스터형 인덱스가 아직 생성되지 않은 경우 고유한 클러스터형 인덱스가 생성되도록 지정할 수 있습니다.
피복지수
이러한 인덱스를 사용하면 특정 쿼리가 테이블 자체의 레코드에 추가로 액세스하지 않고도 인덱스 잎에서 필요한 모든 데이터를 즉시 얻을 수 있습니다.

인덱스 디자인

인덱스는 유용하기 때문에 신중하게 설계해야 합니다. 인덱스는 상당한 디스크 공간을 차지할 수 있으므로 필요한 것보다 더 많은 인덱스를 생성하고 싶지는 않습니다. 또한 데이터 행 자체가 업데이트되면 인덱스도 자동으로 업데이트되므로 추가적인 리소스 오버헤드와 성능 저하가 발생할 수 있습니다. 인덱스를 디자인할 때 데이터베이스 및 이에 대한 쿼리와 관련된 몇 가지 고려 사항을 고려해야 합니다.
데이터 베이스
앞서 언급했듯이 인덱스는 다음과 같은 이유로 시스템 성능을 향상시킬 수 있습니다. 이는 쿼리 엔진에 데이터를 찾는 빠른 방법을 제공합니다. 그러나 데이터를 삽입, 업데이트 또는 삭제하려는 빈도도 고려해야 합니다. 데이터를 변경하면 데이터에 대한 해당 작업을 반영하기 위해 인덱스도 변경되어야 하며, 이로 인해 시스템 성능이 크게 저하될 수 있습니다. 인덱싱 전략을 계획할 때 다음 지침을 고려하십시오.
  • 자주 업데이트되는 테이블의 경우 가능한 한 적은 수의 인덱스를 사용하십시오.
  • 테이블에 많은 양의 데이터가 포함되어 있지만 변경 사항이 미미한 경우 쿼리 성능을 향상시키기 위해 필요한 만큼 많은 인덱스를 사용하십시오. 그러나 작은 테이블에 인덱스를 사용하기 전에 신중하게 생각하십시오. 왜냐하면... 인덱스 검색을 사용하면 단순히 모든 행을 검색하는 것보다 시간이 더 오래 걸릴 수 있습니다.
  • 클러스터형 인덱스의 경우 필드를 최대한 짧게 유지하십시오. 가장 좋은 방법은 고유한 값을 갖고 NULL을 허용하지 않는 열에 클러스터형 인덱스를 사용하는 것입니다. 이것이 기본 키가 클러스터형 인덱스로 자주 사용되는 이유입니다.
  • 열 값의 고유성은 인덱스 성능에 영향을 미칩니다. 일반적으로 열에 중복 항목이 많을수록 인덱스 성능이 저하됩니다. 반면, 고유한 값이 많을수록 인덱스 성능이 좋아집니다. 가능하면 고유 인덱스를 사용하십시오.
  • 복합 인덱스의 경우 인덱스의 열 순서를 고려하세요. 표현식에 사용되는 열 어디(예를 들어, WHERE FirstName = "찰리")이 인덱스의 첫 번째 항목이어야 합니다. 후속 열은 해당 값의 고유성을 기준으로 나열되어야 합니다(고유 값 수가 가장 많은 열이 먼저 표시됨).
  • 특정 요구 사항을 충족하는 경우 계산 열에 인덱스를 지정할 수도 있습니다. 예를 들어 열 값을 가져오는 데 사용되는 식은 결정적이어야 합니다(주어진 입력 매개 변수 집합에 대해 항상 동일한 결과를 반환함).
데이터베이스 쿼리
인덱스를 디자인할 때 고려해야 할 또 다른 사항은 데이터베이스에 대해 실행되는 쿼리입니다. 앞에서 설명한 것처럼 데이터가 얼마나 자주 변경되는지 고려해야 합니다. 또한 다음 원칙을 사용해야 합니다.
  • 여러 개의 단일 쿼리에서 수행하는 대신 하나의 쿼리에서 가능한 한 많은 행을 삽입하거나 수정해 보십시오.
  • 쿼리에서 검색어로 자주 사용되는 열에 대해 비클러스터형 인덱스를 만듭니다. 어디그리고 연결 가입하다.
  • 정확한 값 일치를 위해 행 조회 쿼리에 사용되는 인덱싱 열을 고려하세요.

그리고 지금 실제로는 다음과 같습니다.

SQL Server의 인덱스에 관해 물어보기 당황스러운 14가지 질문

테이블에 두 개의 클러스터형 인덱스를 가질 수 없는 이유는 무엇입니까?

짧은 답변을 원하시나요? 클러스터형 인덱스는 테이블입니다. 테이블에 클러스터형 인덱스를 생성하면 스토리지 엔진은 인덱스 정의에 따라 테이블의 모든 행을 오름차순 또는 내림차순으로 정렬합니다. 클러스터형 인덱스는 다른 인덱스처럼 별도의 엔터티가 아니라 테이블의 데이터를 정렬하고 데이터 행에 대한 빠른 액세스를 촉진하는 메커니즘입니다.
판매 거래 내역이 포함된 테이블이 있다고 가정해 보겠습니다. Sales 테이블에는 주문 ID, 주문 내 항목 위치, 항목 번호, 항목 수량, 주문 번호 및 날짜 등과 같은 정보가 포함됩니다. 열에 클러스터형 인덱스를 만듭니다. 주문 아이디그리고 라인 ID, 다음과 같이 오름차순으로 정렬됩니다. T-SQL암호:
고유한 클러스터형 인덱스 생성 ix_oriderid_lineid ON dbo.Sales(OrderID, LineID);
이 스크립트를 실행하면 테이블의 모든 행이 물리적으로 먼저 OrderID 열을 기준으로 정렬된 다음 LineID를 기준으로 정렬되지만 데이터 자체는 단일 논리 블록인 테이블에 유지됩니다. 이러한 이유로 두 개의 클러스터형 인덱스를 만들 수 없습니다. 하나의 데이터가 포함된 테이블은 하나만 있을 수 있으며 해당 테이블은 특정 순서로 한 번만 정렬될 수 있습니다.

클러스터링된 테이블이 많은 이점을 제공한다면 왜 힙을 사용합니까?

네가 옳아. 클러스터링된 테이블은 훌륭하며 대부분의 쿼리는 클러스터링된 인덱스가 있는 테이블에서 더 나은 성능을 발휘합니다. 그러나 어떤 경우에는 테이블을 자연 그대로의 깨끗한 상태로 두고 싶을 수도 있습니다. 힙 형태로 생성하고 비클러스터형 인덱스만 생성하여 쿼리를 계속 실행하세요.
기억하시겠지만 힙은 데이터를 무작위 순서로 저장합니다. 일반적으로 스토리지 하위 시스템은 데이터가 삽입된 순서대로 테이블에 데이터를 추가하지만, 스토리지 하위 시스템은 보다 효율적인 저장을 위해 행을 이동하는 것도 좋아합니다. 결과적으로 데이터가 어떤 순서로 저장될지 예측할 기회가 없습니다.
쿼리 엔진이 비클러스터형 인덱스의 이점 없이 데이터를 찾아야 하는 경우 테이블 전체 검색을 수행하여 필요한 행을 찾습니다. 매우 작은 테이블에서는 일반적으로 문제가 되지 않지만 힙 크기가 커지면 성능이 빠르게 떨어집니다. 물론 비클러스터형 인덱스는 필요한 데이터가 저장된 파일, 페이지 및 줄에 대한 포인터를 사용하여 도움이 될 수 있습니다. 일반적으로 이는 훨씬 더 많은 것입니다. 최선의 대안테이블을 스캔 중입니다. 그럼에도 불구하고 쿼리 성능을 고려할 때 클러스터형 인덱스의 이점을 비교하는 것은 어렵습니다.
그러나 힙은 특정 상황에서 성능을 향상시키는 데 도움이 될 수 있습니다. 다음과 같은 테이블을 고려해보세요. 큰 금액삽입되지만 데이터 업데이트나 삭제가 자주 발생하지 않습니다. 예를 들어, 로그를 저장하는 테이블은 아카이브되기 전까지 값을 삽입하는 용도로 주로 사용된다. 힙에서는 행이 단순히 힙 끝에 추가되기 때문에 클러스터형 인덱스에서와 같이 페이징 및 데이터 조각화가 표시되지 않습니다. 페이지를 너무 많이 분할하면 성능에 심각한 영향을 미칠 수 있으며 좋은 방법은 아닙니다. 일반적으로 힙을 사용하면 비교적 쉽게 데이터를 삽입할 수 있으며 클러스터형 인덱스에서 발생하는 저장소 및 유지 관리 오버헤드를 처리할 필요가 없습니다.
그러나 데이터 업데이트 및 삭제 부족이 유일한 원인으로 간주되어서는 안됩니다. 데이터가 샘플링되는 방식도 중요한 요소입니다. 예를 들어 데이터 범위를 자주 쿼리하거나 쿼리하는 데이터를 정렬하거나 그룹화해야 하는 경우 힙을 사용하면 안 됩니다.
이는 매우 작은 테이블로 작업하거나 테이블과의 모든 상호 작용이 데이터 삽입으로 제한되고 쿼리가 매우 간단할 때만 힙 사용을 고려해야 한다는 의미입니다(그리고 비클러스터형 인덱스를 사용하고 있음). 그래도). 그렇지 않으면 널리 사용되는 열과 같이 간단한 오름차순 키 필드에 정의된 것과 같이 잘 설계된 클러스터형 인덱스를 사용하십시오. 신원.

기본 색인 채우기 비율을 어떻게 변경합니까?

기본 인덱스 채우기 비율을 변경하는 것은 한 가지입니다. 기본 비율이 어떻게 작동하는지 이해하는 것은 또 다른 문제입니다. 하지만 먼저 몇 걸음 뒤로 물러서세요. 인덱스 채우기 요소는 채우기를 시작하기 전에 맨 아래 수준(리프 수준)에 인덱스를 저장할 페이지 공간의 양을 결정합니다. 새 페이지. 예를 들어 계수를 90으로 설정하면 인덱스가 커지면 페이지의 90%를 차지한 후 다음 페이지로 이동합니다.
기본적으로 인덱스 채우기 비율 값은 다음과 같습니다. SQL 서버 0(100)입니다. 따라서 시스템 표준 값과 다른 값을 코드에 구체적으로 지정하거나 기본 동작을 변경하지 않는 한 모든 새 인덱스는 자동으로 이 설정을 상속합니다. 당신이 사용할 수있는 SQL Server 관리 스튜디오기본값을 조정하거나 시스템 저장 프로시저를 실행하려면 sp_configure. 예를 들어, 다음 세트 T-SQL명령은 계수 값을 90으로 설정합니다(먼저 고급 설정 모드로 전환해야 함).
EXEC sp_configure "고급 옵션 표시", 1; 다시 구성하세요. GO EXEC sp_configure "채우기 비율", 90; 다시 구성하세요. 가다
인덱스 채우기 비율 값을 변경한 후 서비스를 다시 시작해야 합니다. SQL 서버. 이제 지정된 두 번째 인수 없이 sp_configure를 실행하여 설정 값을 확인할 수 있습니다.
EXEC sp_configure "채우기 비율" GO
이 명령은 값 90을 반환해야 합니다. 결과적으로 새로 생성된 모든 인덱스는 이 값을 사용합니다. 인덱스를 생성하고 채우기 비율 값을 쿼리하여 이를 테스트할 수 있습니다.
AdventureWorks2012를 사용하세요. -- 귀하의 데이터베이스 GO CREATE NONCLUSTERED INDEX ix_people_lastname ON Person.Person(LastName); GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
안에 이 예에서는테이블에 비클러스터형 인덱스를 만들었습니다. 사람데이터베이스에서 어드벤처웍스2012. 인덱스를 생성한 후 sys.indexes 시스템 테이블에서 채우기 비율 값을 얻을 수 있습니다. 쿼리는 90을 반환해야 합니다.
그러나 인덱스를 삭제하고 다시 생성했지만 이제 특정 채우기 비율 값을 지정했다고 가정해 보겠습니다.
비클러스터형 인덱스 생성 ix_people_lastname ON Person.Person(LastName) WITH (fillfactor=80); GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
이번에는 지침을 추가했습니다. 와 함께및 옵션 채우기 비율인덱스 생성 작업을 위해 인덱스 생성값 80을 지정했습니다. 연산자 선택하다이제 해당 값을 반환합니다.
지금까지는 모든 것이 매우 간단했습니다. 이 전체 프로세스에서 실제로 화상을 입을 수 있는 부분은 해당 값을 알고 있다고 가정하고 기본 계수 값을 사용하는 인덱스를 생성할 때입니다. 예를 들어, 누군가 서버 설정을 조작하고 너무 고집스러워서 인덱스 채우기 비율을 20으로 설정했습니다. 동시에 기본값이 0이라고 가정하고 인덱스를 계속 생성합니다. 불행하게도 채우기를 찾을 수 있는 방법이 없습니다. 인덱스를 생성하지 않는 한 인수를 고려한 다음 예제에서 했던 것처럼 값을 확인하세요. 그렇지 않으면 뭔가 의심이 들 정도로 쿼리 성능이 떨어지는 순간을 기다려야 할 것입니다.
알아야 할 또 다른 문제는 인덱스를 다시 작성하는 것입니다. 인덱스 생성과 마찬가지로 인덱스를 다시 작성할 때 인덱스 채우기 비율 값을 지정할 수 있습니다. 그러나 create index 명령과 달리 재구축은 겉보기와는 달리 서버 기본 설정을 사용하지 않습니다. 더욱이 인덱스 채우기 비율 값을 구체적으로 지정하지 않으면 SQL 서버구조 조정 이전에 이 지수가 존재했던 계수의 값을 사용합니다. 예를 들어 다음 작업은 인덱스 변경방금 생성한 인덱스를 다시 작성합니다.
ALTER INDEX ix_people_lastname ON Person.Person REBUILD; GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
채우기 비율 값을 확인하면 값이 80으로 표시됩니다. 이는 마지막으로 인덱스를 생성할 때 지정한 값이기 때문입니다. 기본값은 무시됩니다.
보시다시피 인덱스 채우기 비율 값을 변경하는 것은 그리 어렵지 않습니다. 현재의 가치를 알고, 언제 적용되는지 이해하는 것이 훨씬 더 어렵습니다. 인덱스를 생성하고 재구축할 때 항상 계수를 구체적으로 지정하면 항상 특정 결과를 알 수 있습니다. 다른 사람이 서버 설정을 다시 망치지 않도록 걱정할 필요가 없다면 모든 인덱스가 터무니없이 낮은 인덱스 채우기 비율로 다시 작성됩니다.

중복된 항목이 포함된 열에 클러스터형 인덱스를 만들 수 있나요?

예, 아니오. 예, 중복 값이 ​​포함된 키 열에 클러스터형 인덱스를 만들 수 있습니다. 아니요, 키 열의 값은 고유하지 않은 상태로 유지될 수 없습니다. 설명하겠습니다. 열에 고유하지 않은 클러스터형 인덱스를 생성하는 경우 스토리지 엔진은 고유성을 보장하고 따라서 클러스터형 테이블의 각 행을 식별할 수 있도록 중복 값에 고유자를 추가합니다.
예를 들어 고객 데이터가 포함된 열에 클러스터형 인덱스를 만들기로 결정할 수 있습니다. 성을 유지합니다. 열에는 Franklin, Hancock, Washington 및 Smith 값이 포함되어 있습니다. 그런 다음 Adams, Hancock, Smith 및 Smith 값을 다시 삽입합니다. 그러나 키 열의 값은 고유해야 하므로 스토리지 엔진은 중복 항목의 값을 다음과 같이 변경합니다: Adams, Franklin, Hancock, Hancock1234, Washington, Smith, Smith4567 및 Smith5678.
얼핏 보면 이 접근 방식은 괜찮아 보이지만 정수 값을 사용하면 키 크기가 늘어나 중복이 많을 경우 문제가 될 수 있으며, 이 값들은 비클러스터형 인덱스나 외부 인덱스의 기반이 됩니다. 주요 참조. 이러한 이유로 가능하면 항상 고유한 클러스터형 인덱스를 생성하도록 노력해야 합니다. 이것이 불가능하다면, 적어도고유 값의 함량이 매우 높은 열을 사용해 보십시오.

클러스터형 인덱스가 생성되지 않은 경우 테이블은 어떻게 저장됩니까?

SQL 서버두 가지 유형의 테이블, 즉 클러스터형 인덱스가 있는 클러스터형 테이블과 힙 테이블 또는 힙만 지원합니다. 클러스터링된 테이블과 달리 힙의 데이터는 어떤 방식으로도 정렬되지 않습니다. 본질적으로 이는 데이터 더미(힙)입니다. 그러한 테이블에 행을 추가하면 스토리지 엔진은 해당 행을 페이지 끝에 추가합니다. 페이지가 데이터로 채워지면 새 페이지에 추가됩니다. 대부분의 경우 정렬 기능과 더 빠른 쿼리를 활용하기 위해 테이블에 클러스터형 인덱스를 만들고 싶을 것입니다. 전화 번호원칙에 따라 분류되지 않은 주소록). 그러나 클러스터형 인덱스를 만들지 않기로 선택한 경우에도 힙에 비클러스터형 인덱스를 만들 수 있습니다. 이 경우 각 인덱스 행에는 힙 행에 대한 포인터가 있습니다. 색인에는 파일 ID, 페이지 번호 및 데이터 줄 번호가 포함됩니다.

값 고유성 제약 조건과 테이블 인덱스가 있는 기본 키 사이의 관계는 무엇입니까?

기본 키와 고유 제약 조건은 열의 값이 고유함을 보장합니다. 테이블에 대해 하나의 기본 키만 생성할 수 있으며 값을 포함할 수 없습니다. 없는. 테이블 값의 고유성에 대해 여러 가지 제한 사항을 만들 수 있으며 각 제한 사항은 다음과 같은 단일 레코드를 가질 수 있습니다. 없는.
기본 키를 생성할 때 클러스터형 인덱스가 아직 생성되지 않은 경우 스토리지 엔진은 고유한 클러스터형 인덱스도 생성합니다. 그러나 기본 동작을 재정의할 수 있으며 비클러스터형 인덱스가 생성됩니다. 기본 키를 생성할 때 클러스터형 인덱스가 존재하는 경우 고유한 비클러스터형 인덱스가 생성됩니다.
고유 제약 조건을 생성하면 스토리지 엔진은 고유한 비클러스터형 인덱스를 생성합니다. 그러나 이전에 고유한 클러스터형 인덱스를 만들지 않은 경우 고유한 클러스터형 인덱스 생성을 지정할 수 있습니다.
일반적으로 고유 값 제약 조건과 고유 인덱스는 동일합니다.

SQL Server에서 클러스터형 인덱스와 비클러스터형 인덱스를 B-트리라고 부르는 이유는 무엇입니까?

클러스터형이든 비클러스터형이든 SQL Server의 기본 인덱스는 인덱스 노드라는 페이지 집합에 분산됩니다. 이러한 페이지는 균형 트리라는 트리 구조를 사용하여 특정 계층 구조로 구성됩니다. 그림과 같이 최상위 수준에는 루트 노드가 있고, 맨 아래에는 리프 노드가 있으며, 최상위 수준과 최하위 수준 사이에 중간 노드가 있습니다.


루트 노드는 인덱스를 통해 데이터를 검색하려는 쿼리에 대한 기본 진입점을 제공합니다. 이 노드에서 시작하여 쿼리 하위 시스템은 다음을 따라 전환을 시작합니다. 계층적 구조데이터가 포함된 적절한 리프 노드까지 이동합니다.
예를 들어, 키 값 82가 포함된 행을 선택하라는 요청이 수신되었다고 가정해 보겠습니다. 쿼리 하위 시스템은 적합한 중간 노드(여기서는 1-100)를 참조하는 루트 노드에서 작업을 시작합니다. 중간 노드 1-100에서 노드 51-100으로 전환되고 거기에서 최종 노드 76-100으로 전환됩니다. 이것이 클러스터형 인덱스인 경우 노드 리프에는 82와 동일한 키와 연결된 행의 데이터가 포함됩니다. 이것이 비클러스터형 인덱스인 경우 인덱스 리프에는 클러스터형 테이블 또는 테이블의 특정 행에 대한 포인터가 포함됩니다. 힙.

이러한 인덱스 노드를 모두 통과해야 하는 경우 인덱스가 어떻게 쿼리 성능을 향상시킬 수 있습니까?

첫째, 인덱스가 항상 성능을 향상시키는 것은 아닙니다. 잘못 생성된 인덱스가 너무 많으면 시스템이 수렁에 빠지고 쿼리 성능이 저하됩니다. 인덱스를 주의 깊게 적용하면 상당한 성능 향상을 제공할 수 있다고 말하는 것이 더 정확합니다.
성능 튜닝에 관한 방대한 책을 생각해 보십시오. SQL 서버(전자 버전이 아닌 종이 버전). 리소스 관리자 구성에 대한 정보를 찾고 싶다고 가정해 보겠습니다. 책 전체를 페이지별로 손가락으로 드래그하거나 목차를 열고 찾고 있는 정보가 포함된 정확한 페이지 번호를 찾을 수 있습니다(책의 색인이 올바르게 지정되어 있고 목차의 색인이 올바른 경우). 기본 구조(책)에서 필요한 정보를 얻기 위해 먼저 완전히 다른 구조(색인)에 액세스해야 하더라도 이렇게 하면 확실히 상당한 시간을 절약할 수 있습니다.
책의 색인과 마찬가지로 SQL 서버테이블에 포함된 모든 데이터를 완전히 스캔하는 대신 필요한 데이터에 대해 정확한 쿼리를 실행할 수 있습니다. 작은 테이블의 경우 전체 스캔은 일반적으로 문제가 되지 않지만, 큰 테이블은 많은 데이터 페이지를 차지하므로 쿼리 엔진이 데이터의 올바른 위치를 즉시 얻을 수 있는 인덱스가 존재하지 않는 한 쿼리 실행 시간이 상당히 길어질 수 있습니다. 지도도 없이 주요 대도시 앞 다층 도로 교차로에서 길을 잃는다고 상상해 보세요.

인덱스가 그렇게 훌륭하다면 모든 열에 인덱스를 하나씩 생성해 보는 것은 어떨까요?

어떤 선행도 처벌받지 않을 수 없습니다. 적어도 인덱스의 경우는 그렇습니다. 물론, 연산자 가져오기 쿼리를 실행하는 한 인덱스는 훌륭하게 작동합니다. 선택하다, 그러나 교환 원에 대한 빈번한 통화가 시작 되 자마자 끼워 넣다, 업데이트그리고 삭제, 풍경이 매우 빠르게 변합니다.
운영자가 데이터 요청을 시작할 때 선택하다, 쿼리 엔진은 인덱스를 찾고, 트리 구조를 통해 이동하며, 찾고 있는 데이터를 검색합니다. 이보다 더 간단한 것은 무엇일까요? 하지만 다음과 같은 변경 문을 시작하면 상황이 달라집니다. 업데이트. 예, 문의 첫 번째 부분에서 쿼리 엔진은 인덱스를 다시 사용하여 수정 중인 행을 찾을 수 있습니다. 이는 좋은 소식입니다. 그리고 키 열의 변경 사항에 영향을 주지 않는 행의 데이터에 대한 간단한 변경 사항이 있는 경우 변경 프로세스는 전혀 어렵지 않습니다. 그러나 변경으로 인해 데이터가 포함된 페이지가 분할되거나 키 열의 값이 변경되어 다른 인덱스 노드로 이동하게 되면 어떻게 될까요? 이로 인해 인덱스가 관련된 모든 인덱스 및 작업에 영향을 미치는 재구성이 필요할 수 있습니다. , 이로 인해 생산성이 크게 저하됩니다.
교환원을 호출할 때 유사한 프로세스가 발생합니다. 삭제. 인덱스는 삭제되는 데이터를 찾는 데 도움이 될 수 있지만 데이터 자체를 삭제하면 페이지가 다시 섞일 수 있습니다. 운영자에 관해서 끼워 넣다, 모든 인덱스의 주요 적: 많은 양의 데이터를 추가하기 시작하면 인덱스 및 재구성이 변경되고 모두가 고통을 겪습니다.
따라서 생성할 인덱스 유형과 개수를 고려할 때 데이터베이스에 대한 쿼리 유형을 고려하십시오. 더 많다는 것이 더 좋다는 뜻은 아닙니다. 테이블에 새 인덱스를 추가하기 전에 기본 쿼리 비용뿐만 아니라 소비된 디스크 공간의 양, 기능 및 인덱스 유지 관리 비용(다른 작업에 도미노 효과를 초래할 수 있음)도 고려하세요. 인덱스 디자인 전략은 구현의 가장 중요한 측면 중 하나이며 인덱스 크기, 고유 값 수, 인덱스가 지원할 쿼리 유형에 이르기까지 많은 고려 사항을 포함해야 합니다.

기본 키가 있는 열에 클러스터형 인덱스를 만들어야 합니까?

필수 조건을 충족하는 모든 열에 클러스터형 인덱스를 만들 수 있습니다. 클러스터형 인덱스와 기본 키 제약 조건은 서로를 위해 만들어지고 천생연분이 되는 것이 사실이므로, 기본 키를 생성할 때 클러스터형 인덱스가 없으면 자동으로 클러스터형 인덱스가 생성된다는 점을 이해하시기 바랍니다. 이전에 생성되었습니다. 그러나 클러스터형 인덱스가 다른 곳에서 더 나은 성능을 발휘할 것이라고 결정할 수 있으며, 종종 귀하의 결정이 타당할 수도 있습니다.
클러스터형 인덱스의 주요 목적은 인덱스를 정의할 때 지정된 키 열을 기반으로 테이블의 모든 행을 정렬하는 것입니다. 이는 다음을 제공합니다 빠른 탐색그리고 쉬운 접근테이블 데이터에.
테이블의 기본 키는 추가 데이터를 추가하지 않고도 테이블의 각 행을 고유하게 식별하므로 좋은 선택이 될 수 있습니다. 일부 경우에 최선의 선택고유할 뿐만 아니라 크기가 작고 값이 순차적으로 증가하는 대리 기본 키가 있으므로 이 값을 기반으로 하는 비클러스터형 인덱스를 보다 효율적으로 만듭니다. 또한 쿼리 최적화 프로그램은 클러스터형 인덱스와 기본 키의 이러한 조합을 선호합니다. 테이블을 조인하는 것이 기본 키와 관련 클러스터형 인덱스를 사용하지 않는 다른 방식으로 조인하는 것보다 빠르기 때문입니다. 내가 말했듯이 그것은 하늘에서 이루어진 일치입니다.
그러나 마지막으로 클러스터형 인덱스를 생성할 때 이를 기반으로 하는 비클러스터형 인덱스 수, 키 인덱스 열의 값이 얼마나 자주 변경되는지, 크기는 얼마나 되는지 등 고려해야 할 여러 측면이 있다는 점에 유의할 가치가 있습니다. 클러스터형 인덱스의 열 값이 변경되거나 인덱스가 예상대로 수행되지 않으면 테이블의 다른 모든 인덱스가 영향을 받을 수 있습니다. 클러스터형 인덱스는 값이 특정 순서로 증가하지만 무작위 방식으로 변경되지 않는 가장 지속적인 열을 기반으로 해야 합니다. 인덱스는 테이블에서 가장 자주 액세스되는 데이터에 대한 쿼리를 지원해야 하므로 쿼리는 데이터가 인덱스의 잎인 루트 노드에서 정렬되고 액세스 가능하다는 사실을 최대한 활용합니다. 기본 키가 이 시나리오에 적합하면 이를 사용하십시오. 그렇지 않은 경우 다른 열 세트를 선택하십시오.

뷰를 인덱싱하면 여전히 뷰인가요?

프레젠테이션은 가상 테이블, 하나 이상의 테이블에서 데이터를 생성합니다. 기본적으로 해당 뷰를 쿼리할 때 기본 테이블에서 데이터를 검색하는 명명된 쿼리입니다. 테이블에 인덱스를 만드는 방법과 유사하게 이 뷰에 클러스터형 인덱스와 비클러스터형 인덱스를 만들어 쿼리 성능을 향상시킬 수 있지만, 주의할 점은 먼저 클러스터형 인덱스를 만든 다음 비클러스터형 인덱스를 만들 수 있다는 것입니다.
인덱싱된 뷰(구체화된 뷰)가 생성되면 뷰 정의 자체는 별도의 엔터티로 유지됩니다. 이는 결국 하드코딩된 연산자일 뿐입니다. 선택하다, 데이터베이스에 저장됩니다. 그러나 지수는 완전히 다른 이야기입니다. 공급자에 클러스터형 또는 비클러스터형 인덱스를 생성하면 데이터는 일반 인덱스와 마찬가지로 디스크에 물리적으로 저장됩니다. 또한 기본 테이블의 데이터가 변경되면 뷰의 인덱스도 자동으로 변경됩니다. 즉, 자주 변경되는 테이블에 대한 뷰 인덱싱을 피하는 것이 좋습니다. 어쨌든 뷰는 뷰로 유지됩니다. 즉, 테이블을 살펴보지만 정확하게 실행되는 것은 다음과 같습니다. 이 순간, 이에 해당하는 인덱스가 있습니다.
뷰에 인덱스를 생성하려면 먼저 여러 제약 조건을 충족해야 합니다. 예를 들어, 뷰는 기본 테이블만 참조할 수 있고 다른 뷰는 참조할 수 없으며 해당 테이블은 동일한 데이터베이스에 있어야 합니다. 실제로는 그 밖에도 많은 제한사항이 있으므로 해당 문서를 꼭 확인하세요. SQL 서버모든 더러운 세부 사항에 대해.

복합 인덱스 대신 커버링 인덱스를 사용하는 이유는 무엇입니까?

먼저, 둘 사이의 차이점을 확실히 이해해 봅시다. 복합 인덱스는 단순히 두 개 이상의 열을 포함하는 일반 인덱스입니다. 여러 키 열을 사용하여 각 열이 고유한지 확인할 수 있습니다. 테이블 행, 고유성을 보장하기 위해 기본 키가 여러 열로 구성되거나 여러 열에서 자주 호출되는 쿼리의 실행을 최적화하려고 할 수도 있습니다. 그러나 일반적으로 인덱스에 포함된 키 열이 많을수록 인덱스 효율성이 떨어지므로 복합 인덱스를 신중하게 사용해야 합니다.
언급한 바와 같이 필요한 모든 데이터가 인덱스 자체와 마찬가지로 인덱스의 리프에 즉시 위치하면 쿼리에 큰 이점이 있을 수 있습니다. 클러스터형 인덱스에서는 문제가 되지 않습니다. 모든 데이터가 이미 거기에 있습니다. 따라서 클러스터형 인덱스를 만들 때 신중하게 생각하는 것이 중요합니다. 그러나 잎의 비클러스터형 인덱스에는 키 열만 포함됩니다. 다른 모든 데이터에 액세스하려면 쿼리 최적화 프로그램에 추가 단계가 필요하며, 이로 인해 쿼리 실행에 상당한 오버헤드가 추가될 수 있습니다.
커버링 인덱스가 구출되는 곳입니다. 비클러스터형 인덱스를 정의할 때 키 열에 추가 열을 지정할 수 있습니다. 예를 들어 애플리케이션이 열 데이터를 자주 쿼리한다고 가정해 보겠습니다. 주문 아이디그리고 주문 날짜테이블에 매상:
SELECT OrderID, OrderDate FROM Sales WHERE OrderID = 12345;
두 열 모두에 복합 비클러스터형 인덱스를 만들 수 있지만 OrderDate 열은 특별히 유용한 키 열 역할을 하지 않고 인덱스 유지 관리 오버헤드만 추가합니다. 최선의 결정키 열에 포함 인덱스를 만드는 것입니다. 주문 아이디그리고 추가로 포함된 열 주문 날짜:
비클러스터형 인덱스 생성 ix_orderid ON dbo.Sales(OrderID) INCLUDE(OrderDate);
이렇게 하면 중복 열을 인덱싱할 때 발생하는 단점을 방지하는 동시에 쿼리를 실행할 때 리프에 데이터를 저장하는 이점을 계속 유지할 수 있습니다. 포함된 열은 키의 일부가 아니지만 데이터는 리프 노드인 인덱스 리프에 저장됩니다. 이를 통해 추가 오버헤드 없이 쿼리 성능을 향상시킬 수 있습니다. 또한 포함 인덱스에 포함된 열은 인덱스의 키 열보다 제한이 적습니다.

키 열의 중복 수가 중요합니까?

인덱스를 생성할 때 키 열의 중복 수를 줄이도록 노력해야 합니다. 또는 더 정확하게는 반복률을 가능한 한 낮게 유지하려고 노력하십시오.
복합 인덱스로 작업하는 경우 중복은 모든 키 열에 전체적으로 적용됩니다. 단일 열에는 많은 중복 값이 ​​포함될 수 있지만 모든 인덱스 열 간에는 반복이 최소화되어야 합니다. 예를 들어 열에 복합 비클러스터형 인덱스를 생성합니다. 이름그리고 , John Doe 값과 Doe 값을 많이 가질 수 있지만 가능한 한 John Doe 값을 적게 가지거나 John Doe 값을 하나만 갖는 것이 좋습니다.
키 컬럼 값의 고유성 비율을 인덱스 선택성이라고 합니다. 고유 값이 많을수록 선택성이 높아집니다. 고유 인덱스는 가능한 선택성이 가장 높습니다. 쿼리 엔진은 선택도 값이 높은 열을 선호합니다. 특히 가장 자주 실행되는 쿼리의 WHERE 절에 해당 열이 포함되어 있는 경우 더욱 그렇습니다. 인덱스를 더 선택적으로 선택할수록 쿼리 엔진이 결과 데이터 세트의 크기를 더 빠르게 줄일 수 있습니다. 물론 단점은 상대적으로 고유한 값이 적은 열은 인덱싱에 좋은 후보가 될 가능성이 거의 없다는 것입니다.

키 열 데이터의 특정 하위 집합에만 비클러스터형 인덱스를 생성할 수 있습니까?

기본적으로 비클러스터형 인덱스에는 테이블의 각 행에 대해 하나의 행이 포함됩니다. 물론, 그러한 인덱스가 테이블이라고 가정하면 클러스터형 인덱스에 대해서도 같은 말을 할 수 있습니다. 하지만 비클러스터형 인덱스의 경우 버전부터 시작하기 때문에 일대일 관계가 중요한 개념입니다. SQL 서버 2008을 사용하면 포함된 행을 제한하는 필터링 가능한 인덱스를 생성할 수 있습니다. 필터링된 인덱스는 다음과 같은 이유로 쿼리 성능을 향상시킬 수 있습니다. 크기가 더 작고 모든 표 형식보다 더 정확한 필터링된 통계가 포함되어 있어 향상된 실행 계획이 생성됩니다. 필터링된 인덱스에는 더 적은 저장 공간과 유지 관리 비용이 필요합니다. 필터와 일치하는 데이터가 변경되는 경우에만 인덱스가 업데이트됩니다.
또한 필터링 가능한 인덱스를 쉽게 만들 수 있습니다. 연산자에서 인덱스 생성당신은 단지 어디필터 상태. 예를 들어, 코드에 표시된 대로 인덱스에서 NULL을 포함하는 모든 행을 필터링할 수 있습니다.
CarrierTrackingNumber가 NULL이 아닌 Sales.SalesOrderDetail(CarrierTrackingNumber)에 비클러스터형 인덱스 ix_trackingnumber를 생성합니다.
실제로 중요한 쿼리에서 중요하지 않은 데이터를 필터링할 수 있습니다. 하지만 조심하세요 왜냐하면... SQL 서버뷰에서 필터링 가능한 인덱스를 생성할 수 없는 등 필터링 가능한 인덱스에 몇 가지 제한 사항을 적용하므로 설명서를 주의 깊게 읽어보세요.
인덱싱된 뷰를 만들어 비슷한 결과를 얻을 수도 있습니다. 그러나 필터링된 인덱스에는 유지 관리 비용을 줄이고 실행 계획의 품질을 향상시키는 기능과 같은 여러 가지 장점이 있습니다. 필터링된 인덱스는 온라인으로 다시 작성할 수도 있습니다. 인덱싱된 뷰를 사용해 보세요.

그리고 다시 번역가로부터 조금

등장의 목적 이 번역의 Habrahabr 페이지에서는 다음의 SimpleTalk 블로그에 대해 알려주거나 상기시키기 위한 것이었습니다. 레드게이트.
재미있고 흥미로운 게시물을 많이 게시합니다.
나는 어떤 회사 제품과도 관련이 없습니다 레드게이트, 판매도 마찬가지입니다.

약속대로 더 알고 싶은 분들을 위한 책
나는 나 자신이 쓴 아주 좋은 책 세 권을 추천합니다(링크는 다음으로 연결됩니다). 빛나다매장에 있는 버전 아마존):

원칙적으로 간단한 인덱스를 열 수 있습니다. 태그 추가
Microsoft SQL Server 2012 T-SQL 기본 사항(개발자 참조)
저자 이직 벤간
출판일: 2012년 7월 15일
기술의 대가인 저자는 다음과 같이 말합니다. 기본 지식데이터베이스 작업에 대해.
모든 것을 잊어버렸거나 전혀 몰랐다면 확실히 읽어 볼 가치가 있습니다.

ROWID 인덱스테이블 열의 모든 값과 해당 열 값이 포함된 테이블의 모든 행에 대한 ROWID를 표시하는 데이터베이스 개체입니다.

ROWID테이블의 행에 대한 고유 식별자이며 실제로 해당 특정 행의 정확한 물리적 위치를 설명하는 의사 열입니다. 이 정보를 바탕으로 신탁이후에 테이블 행과 연관된 데이터를 찾을 수 있습니다. 행을 이동하거나, 내보내거나, 가져오거나 위치를 변경하는 기타 작업을 수행할 때마다 ROWID선은 다른 물리적 위치를 차지하기 때문입니다. 데이터 저장용 ROWID 80비트(10바이트)가 필요합니다. 식별자 ROWID객체 번호(32비트), 상대 파일 번호(10비트), 블록 번호(22비트) 및 라인 번호(16비트)의 네 가지 구성 요소로 구성됩니다. 이러한 식별자는 데이터베이스의 데이터 위치를 나타내는 18자 시퀀스로 표시되며 각 문자는 다음과 같이 Base-64 형식으로 표시됩니다. 문자 A-Z, a~z, 0~9, + 및 /. 처음 6자는 데이터 객체 번호이고, 다음 3자는 상대 파일 번호, 다음 6자는 블록 번호, 마지막 3자는 라인 번호입니다.

예:

선택 가족, ROWID학생으로부터;

ROWID

——————————————

이바노프 AAAA3kAAGAAAAGsAAA

페트로프 AAAA3kAAGAAAAGsAAB

데이터베이스에서 신탁인덱스는 데이터베이스 값의 고유성을 보장하고, 테이블에서 레코드 검색 성능을 향상시키는 등 다양한 목적으로 사용됩니다. 검색 기준에 인덱스된 열에 대한 참조를 포함하면 성능이 향상됩니다. 테이블의 데이터에 대해. 안에 신탁 LONG 열을 제외한 모든 테이블 열에 인덱스를 만들 수 있습니다. 인덱스는 특히 대규모 테이블로 작업할 때 속도에 민감하지 않은 애플리케이션과 고성능 애플리케이션을 구별합니다. 그러나 인덱스 생성을 결정하기 전에 시스템 성능에 대한 장단점을 따져볼 필요가 있습니다. 단순히 색인을 입력하고 잊어버리면 성능이 향상되지 않습니다.

모든 값이 고유한 열에 인덱스를 생성하면 성능이 가장 크게 향상되지만, 중복되거나 NULL 값이 포함된 열에 대해서도 비슷한 결과를 얻을 수 있습니다. 인덱스를 생성하기 위해 열 값이 고유할 필요는 없습니다. 다음은 표준 인덱스를 사용할 때 원하는 성능 향상을 달성하는 데 도움이 되는 몇 가지 권장 사항이며, 인덱스를 생성할 때 성능과 디스크 공간 소비 간의 균형과 관련된 문제도 살펴보겠습니다.

인덱스를 사용하여 테이블의 정보를 조회하면 열이 인덱스되지 않은 테이블을 검색하는 것보다 성능이 크게 향상될 수 있습니다. 그러나 올바른 인덱스를 선택하는 것은 결코 쉬운 일이 아닙니다. 물론, B-tree 인덱스로 인덱싱하기 위해서는 값이 모두 고유한 컬럼이 바람직하지만, 이러한 요구 사항을 충족하지 못하는 컬럼도 해당 행의 약 10% 정도가 동일한 값을 포함하는 한 좋은 후보가 됩니다. 그리고 더 이상은 없습니다. 예를 들어 개인의 성별에 대한 정보를 저장하는 "스위치" 또는 "플래그" 열은 B-트리 인덱스에 적합하지 않습니다. 소수의 "신뢰할 수 있는 값"을 저장하는 데 사용되는 열과 특정 값도 적합하지 않습니다. 예를 들어 "신뢰성" 또는 "신뢰할 수 없음", "활성" 또는 "비활성", "예" 또는 "아니요" 등의 기호를 표시합니다. 마지막으로 역방향 키가 있는 인덱스는 다음과 같습니다. 일반적으로 설치 및 작동되는 곳에서 사용됩니다. 신탁병렬 서버 및 데이터베이스의 병렬 처리 수준을 최대로 높여야 합니다.

우선, 그것이 무엇인지 알아내는 것이 좋습니다. 커버링 인덱스, Habré에 관한 기사에서 발췌하겠습니다.

복합 인덱스 대신 커버링 인덱스를 사용하는 이유는 무엇입니까?
먼저, 둘 사이의 차이점을 확실히 이해해 봅시다.
종합지수이는 둘 이상의 열을 포함하는 일반 인덱스일 뿐입니다. 여러 키 열을 사용하여 테이블의 각 행이 고유한지 확인하거나, 기본 키가 고유한지 확인하기 위해 여러 열을 가질 수도 있고, 여러 열에서 자주 호출되는 쿼리 실행을 최적화하려고 할 수도 있습니다. 그러나 일반적으로 인덱스에 포함된 키 열이 많을수록 인덱스 효율성이 떨어지므로 복합 인덱스를 신중하게 사용해야 합니다.

언급한 바와 같이 필요한 모든 데이터가 인덱스 자체와 마찬가지로 인덱스의 리프에 즉시 위치하면 쿼리에 큰 이점이 있을 수 있습니다. 클러스터형 인덱스에서는 문제가 되지 않습니다. 모든 데이터가 이미 거기에 있습니다. 따라서 클러스터형 인덱스를 만들 때 신중하게 생각하는 것이 중요합니다. 그러나 잎의 비클러스터형 인덱스에는 키 열만 포함됩니다. 다른 모든 데이터에 액세스하려면 쿼리 최적화 프로그램에 추가 단계가 필요하며, 이로 인해 쿼리 실행에 상당한 오버헤드가 추가될 수 있습니다.

바로 그곳이다 커버링 인덱스구조하러 달려갑니다. 비클러스터형 인덱스를 정의할 때 키 열에 추가 열을 지정할 수 있습니다.

따라서 포함 인덱스에는 인덱스 트리 구조에서 쿼리의 선택 가능한 모든 열이 포함되어서는 안 되며, 쿼리의 데이터를 필터링하거나 그룹화하는 데 사용되는 열만 포함되어야 하며, SELECT 섹션의 나머지 열은 인덱스의 INCLUDE 섹션입니다.

다른 질문의 답변이 도움이 될 수도 있습니다.

위의 예에서는 포함 인덱스 대신 3필드 복합 인덱스를 사용합니다. 포함 인덱스를 생성하는 코드는 다음과 같습니다.

에 비클러스터형 인덱스를 생성합니다. ( ASC) INCLUDE (, ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON

귀하의 질문에 답변하려면:

포함 인덱스의 경우 INCLUDE 섹션의 열 순서 중요하지 않다, 그러나 복합 인덱스에서는 열의 순서가 중요합니다., 왜냐하면 컬럼 데이터는 컬럼이 나열된 순서대로 인덱스 트리에 배치되며, 쿼리 최적화 프로그램은 2열 인덱스를 사용하여 2개 컬럼의 값만 조회할 수 없습니다. 그림에서 2개 열(EMPLOYEE_ID, SUBSIDIARY_ID)의 인덱스 구조가 어떻게 보이는지 명확한 예를 볼 수 있습니다.

1) 지수의 개념
색인하나 이상의 열 값을 기반으로 테이블 행에 대한 빠른 액세스를 제공하는 도구입니다.

표준이 성능 문제를 다루지 않기 때문에 표준화되지 않았기 때문에 이 연산자에는 많은 다양성이 있습니다.

2) 인덱스 생성
인덱스 생성
에()

3) 인덱스 변경 및 삭제
인덱스 활동을 제어하기 위해 연산자가 사용됩니다.
인덱스 변경
인덱스를 제거하려면 다음 연산자를 사용하십시오.
드롭 인덱스

a) 테이블 선택 규칙
1. 행의 5% 이하가 선택되는 테이블을 인덱싱하는 것이 좋습니다.
2. SELECT 문의 WHERE 절에 중복된 테이블이 없는 테이블은 인덱싱해야 한다.
3. 자주 업데이트되는 테이블을 색인화하는 것은 실용적이지 않습니다.
4. 2페이지 이하(Oracle의 경우 300행 미만)를 차지하는 테이블을 인덱스하는 것은 전체 스캔에 더 오랜 시간이 걸리지 않으므로 부적절합니다.

b) 열 선택 규칙
1. 기본 및 외래 키 - 테이블 조인, 데이터 검색 및 검색에 자주 사용됩니다. 이는 항상 최대의 유용성을 갖춘 고유 인덱스입니다.
2. 참조 무결성 옵션을 사용하는 경우 항상 FK에 대한 인덱스가 필요합니다.
3. 데이터가 종종 정렬 및/또는 그룹화되는 열입니다.
4. SELECT 문의 WHERE 절에서 자주 검색되는 컬럼.
5. 긴 설명 열에 인덱스를 생성하면 안 됩니다.

c) 복합지수 생성 원칙
1. 개별 열에 고유한 값이 거의 없으면 복합 인덱스가 좋지만 복합 인덱스가 더 많은 고유성을 제공합니다.
2. SELECT 문으로 선택한 값이 모두 복합 인덱스에 속해 있으면 해당 인덱스에서 해당 값이 선택됩니다.
3. WHERE 절에서 AND 연산자와 결합된 2개 이상의 값을 사용하는 경우에는 복합 인덱스를 생성해야 합니다.

d) 생성하는 것은 권장되지 않습니다.
복합 인덱스를 포함하여 열에 다음과 같은 인덱스를 생성하는 것은 권장되지 않습니다.
1. 쿼리 결과 검색, 병합, 정렬에는 거의 사용되지 않습니다.
2. 자주 변경되는 값을 포함해야 합니다. 빈번한 업데이트인덱스는 데이터베이스 성능을 저하시킵니다.
3. 소수의 고유 값(10% m/f 미만) 또는 하나 또는 두 개의 값을 가진 다수의 라인을 포함합니다(공급자의 거주 도시는 모스크바입니다).
4. WHERE 절에 함수나 표현식이 적용되어 인덱스가 작동하지 않습니다.

e) 우리는 잊지 말아야 한다
인덱스 수가 많으면 데이터 업데이트 속도가 느려지므로 인덱스 수를 줄이기 위해 노력해야 합니다. 따라서 MS SQL Server에서는 테이블당 16개 이하의 인덱스를 생성할 것을 권장합니다.
일반적으로 인덱스는 쿼리 목적과 참조 무결성 유지를 위해 생성됩니다.
인덱스가 쿼리에 사용되지 않는 경우 삭제해야 하며 트리거를 사용하여 참조 무결성을 보장해야 합니다.