[sql-server] 클러스터형 및 비 클러스터형 인덱스는 실제로 무엇을 의미합니까?

DB에 대한 노출이 제한되어 있으며 응용 프로그램 프로그래머로 DB 만 사용했습니다. 나는에 대해 알고 싶어 Clustered하고 Non clustered indexes. 내가 봤는데 내가 찾은 것은 :

클러스터형 인덱스는 테이블의 레코드가 실제로 저장되는 방식을 재정렬하는 특수한 유형의 인덱스입니다. 따라서 테이블에는 하나의 클러스터형 인덱스 만있을 수 있습니다. 클러스터형 인덱스의 리프 노드에는 데이터 페이지가 포함됩니다. 비 클러스터형 인덱스는 인덱스의 논리적 순서가 디스크에있는 행의 물리적 저장된 순서와 일치하지 않는 특수한 유형의 인덱스입니다. 비 클러스터형 인덱스의 리프 노드는 데이터 페이지로 구성되지 않습니다. 대신 리프 노드에는 인덱스 행이 포함됩니다.

내가 찾은 것은 클러스터형 인덱스와 비 클러스터형 인덱스의 차이점무엇입니까? .

누군가 이것을 일반 영어로 설명 할 수 있습니까?



답변

클러스터형 인덱스를 사용하면 행이 인덱스와 동일한 순서로 디스크에 실제로 저장됩니다. 따라서 클러스터 된 인덱스는 하나만있을 수 있습니다.

비 클러스터형 인덱스에는 실제 행에 대한 포인터가있는 두 번째 목록이 있습니다. 각각의 새 인덱스가 새 레코드를 작성하는 데 걸리는 시간이 늘어나더라도 클러스터되지 않은 많은 인덱스를 가질 수 있습니다.

모든 열을 다시 가져 오려면 일반적으로 클러스터형 인덱스에서 읽는 것이 더 빠릅니다. 먼저 색인으로 이동 한 다음 테이블로 이동할 필요가 없습니다.

데이터를 다시 정렬해야 할 경우 클러스터형 인덱스가있는 테이블에 쓰는 것이 느려질 수 있습니다.


답변

클러스터형 인덱스는 데이터베이스에서 실제로 가까운 값을 디스크에서 서로 가깝게 저장하도록 지시하는 것을 의미합니다. 이는 클러스터 된 인덱스 값의 일부 범위로 떨어지는 레코드의 빠른 스캔 / 검색 이점이 있습니다.

예를 들어 Customer 테이블과 Order 테이블이 있습니다.

Customer
----------
ID
Name
Address

Order
----------
ID
CustomerID
Price

특정 고객의 모든 주문을 빠르게 검색하려는 경우 주문 테이블의 “CustomerID”열에 클러스터형 인덱스를 만들 수 있습니다. 이런 식으로 동일한 CustomerID를 가진 레코드는 디스크 (클러스터)에 서로 가까이 물리적으로 저장되어 검색 속도가 빨라집니다.

PS CustomerID의 인덱스는 분명히 고유하지 않으므로 인덱스를 “유일 화”하기 위해 두 번째 필드를 추가하거나 데이터베이스가이를 처리하도록하지만 다른 이야기입니다.

여러 인덱스에 대하여. 데이터가 실제로 배열되는 방식을 정의하므로 테이블 당 하나의 클러스터형 인덱스 만 가질 수 있습니다. 비유를 원한다면 테이블이 많은 큰 방을 상상해보십시오. 이 테이블을 여러 행으로 만들거나 모두 모아서 큰 회의 테이블을 만들 수 있지만 동시에 두 방법을 모두 사용할 수는 없습니다. 테이블은 다른 인덱스를 가질 수 있으며, 클러스터 된 인덱스의 항목을 가리키고 결국 실제 데이터를 찾을 위치를 알려줍니다.


답변

SQL Server 행 지향 스토리지에서 클러스터 및 비 클러스터형 인덱스는 모두 B 트리로 구성됩니다.

여기에 이미지 설명을 입력하십시오

( 이미지 소스 )

클러스터 인덱스와 비 클러스터 인덱스의 주요 차이점은 클러스터 인덱스의 리프 레벨이 있다는 것입니다 이다 테이블. 이것은 두 가지 의미가 있습니다.

  1. 클러스터 된 인덱스 리프 페이지의 행은 항상 포함 뭔가 테이블에있는 (비 스파 스)의 각 열 (값 또는 실제 값에 대한 포인터 중 하나를).
  2. 클러스터형 인덱스는 테이블의 기본 복사본입니다.

클러스터되지 않은 인덱스는 INCLUDE키가 아닌 모든 열을 명시 적으로 포함하기 위해 SQL Server 2005 이후 절 을 사용하여 포인트 1을 수행 할 수 있지만 2 차 표현이며 항상 다른 데이터 복사본 (테이블 자체)이 있습니다.

CREATE TABLE T
(
A INT,
B INT,
C INT,
D INT
)

CREATE UNIQUE CLUSTERED INDEX ci ON T(A,B)
CREATE UNIQUE NONCLUSTERED INDEX nci ON T(A,B) INCLUDE (C,D)

위의 두 지수는 거의 동일합니다. 키 열에 대한 값이 포함 된 상위 수준 색인 페이지 A,B와 다음을 포함하는 리프 수준 페이지A,B,C,D

데이터 행 자체는 한 순서로만 정렬 될 수 있으므로 테이블 당 하나의 클러스터형 인덱스 만있을 수 있습니다.

SQL Server 온라인 설명서의 위 인용문은 많은 혼란을 야기합니다.

내 의견으로는 그것은 훨씬 더 나은 표현이 될 것입니다.

클러스터 된 인덱스의 리프 수준 행이 있기 때문에 테이블 당 하나의 클러스터 된 인덱스가있을 수 있습니다 테이블 행.

온라인 설명서는 정확하지 않지만 클러스터되지 않은 인덱스와 클러스터 된 인덱스의 “정렬”은 논리적이지 않은 것이 분명합니다. 링크 된 목록을 따라 리프 레벨에서 페이지를 읽고 슬롯 배열 순서로 페이지의 행을 읽는 경우 색인 행을 정렬 된 순서대로 읽지 만 실제로는 페이지가 정렬되지 않을 수 있습니다. 일반적으로 클러스터 된 인덱스를 사용하면 인덱스 가 false 인 순서대로 행이 디스크에 물리적으로 항상 저장됩니다 .

이것은 터무니없는 구현입니다. 예를 들어 행이 4GB 테이블 가운데에 삽입 된 경우 SQL Server는 새로 삽입 된 행을위한 공간을 만들기 위해 파일에 2GB의 데이터를 복사 필요 가 없습니다 .

대신 페이지 분할이 발생합니다. 클러스터형 및 비 클러스터형 인덱스의 리프 수준에있는 각 페이지 File:Page에는 다음 및 이전 페이지 의 주소 ( )가 논리 키 순서로 있습니다. 이 페이지는 연속적이거나 키 순서 일 필요는 없습니다.

예를 들어 링크 된 페이지 체인은 1:2000 <-> 1:157 <-> 1:7053

페이지 분할이 발생하면 새 페이지가 파일 그룹의 어느 위치에서나 (소형 테이블의 경우 혼합 범위 또는 해당 오브젝트에 속하는 비어 있지 않은 균일 범위 또는 새로 할당 된 균일 범위에서) 할당됩니다. 파일 그룹에 둘 이상의 파일이 포함되어 있으면 동일한 파일에 없을 수도 있습니다.

논리적 순서와 연속성이 이상적인 물리적 버전과 다른 정도는 논리적 조각화 정도입니다.

단일 파일로 새로 만든 데이터베이스에서 다음을 실행했습니다.

CREATE TABLE T
  (
     X TINYINT NOT NULL,
     Y CHAR(3000) NULL
  );

CREATE CLUSTERED INDEX ix
  ON T(X);

GO

--Insert 100 rows with values 1 - 100 in random order
DECLARE @C1 AS CURSOR,
        @X  AS INT

SET @C1 = CURSOR FAST_FORWARD
FOR SELECT number
    FROM   master..spt_values
    WHERE  type = 'P'
           AND number BETWEEN 1 AND 100
    ORDER  BY CRYPT_GEN_RANDOM(4)

OPEN @C1;

FETCH NEXT FROM @C1 INTO @X;

WHILE @@FETCH_STATUS = 0
  BEGIN
      INSERT INTO T (X)
      VALUES        (@X);

      FETCH NEXT FROM @C1 INTO @X;
  END

그런 다음 페이지 레이아웃을 확인했습니다.

SELECT page_id,
       X,
       geometry::Point(page_id, X, 0).STBuffer(1)
FROM   T
       CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
ORDER  BY page_id

결과는 도처에 있었다. 키 순서의 첫 번째 행 (값 1-아래 화살표로 강조 표시됨)은 거의 실제 페이지에있었습니다.

여기에 이미지 설명을 입력하십시오

논리적 순서와 물리적 순서 사이의 상관 관계를 증가시키기 위해 인덱스를 재구성하거나 재구성하여 조각화를 줄이거 나 제거 할 수 있습니다.

실행 후

ALTER INDEX ix ON T REBUILD;

나는 다음을 얻었다

여기에 이미지 설명을 입력하십시오

테이블에 클러스터형 인덱스가 없으면 힙이라고합니다.

비 클러스터형 인덱스는 힙 또는 클러스터형 인덱스에 구축 할 수 있습니다. 그들은 항상 기본 테이블로 돌아가는 행 로케이터를 포함합니다. 힙의 경우 이것은 물리적 행 식별자 (rid)이며 3 개의 구성 요소 (File : Page : Slot)로 구성됩니다. 클러스터형 인덱스의 경우 행 로케이터는 논리적입니다 (클러스터형 인덱스 키).

후자의 경우 비 클러스터형 인덱스에 이미 CI 키 열이 NCI 키 열 또는 INCLUDE-d 열로 이미 포함되어 있으면 아무 것도 추가되지 않습니다. 그렇지 않으면 누락 된 CI 키 열이 자동으로 NCI에 추가됩니다.

SQL Server는 항상 키 열이 두 유형의 인덱스에 대해 고유한지 확인합니다. 그러나 고유하게 선언되지 않은 인덱스에 대해 적용되는 메커니즘은 두 인덱스 유형마다 다릅니다.

클러스터 된 인덱스 uniquifier는 기존 행을 복제하는 키 값이있는 행에 대해 추가됩니다. 이것은 오름차순 정수입니다.

고유 한 SQL Server로 선언되지 않은 비 클러스터형 인덱스의 경우 행 로케이터를 비 클러스터형 인덱스 키에 자동으로 추가합니다. 이것은 실제로 중복되는 행뿐만 아니라 모든 행에 적용됩니다.

클러스터형 및 비 클러스터 명명법은 열 저장소 인덱스에도 사용됩니다. SQL Server 열 저장소에 대한 종이 향상 상태

열 저장소 데이터는 실제로 어떤 키에서도 “클러스터”되지는 않지만 기본 인덱스를 클러스터형 인덱스라고하는 전통적인 SQL Server 규칙을 유지하기로 결정했습니다.


답변

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 위의 정답을 설명하는 데 도움이되는 유추를 제공 할 것이라고 생각했습니다.

클러스터형 인덱스

공공 도서관에 들어가면 책이 모두 특정 순서로 배열되어 있음을 알게 될 것입니다 (대부분 Dewey Decimal System 또는 DDS). 이것은 책 의 “클러스터형 인덱스” 에 해당합니다. 원하는 책의 DDS #가 005.7565 F736s(이)라면 레이블이 붙은 책꽂이 행 001-099이나 그와 비슷한 것을 찾아서 시작 합니다. 스택의 끝에있는이 끝 표시 부호는 색인의 “중간 노드”에 해당합니다. 결국이라고 표시된 특정 선반으로 드릴 다운 005.7450 - 005.7600한 다음 지정된 DDS #가있는 책을 찾을 때까지 스캔합니다. 그 시점에서 당신은 당신의 책을 찾았습니다.

비 클러스터형 인덱스

그러나 책의 DDS #를 암기 한 상태로 라이브러리에 들어오지 않은 경우 보조 인덱스가 필요합니다. 옛날에는 도서관 앞쪽에 “카드 카탈로그”라고 알려진 멋진 서랍장을 찾을 수있었습니다. 이 책에는 수천 권의 3×5 카드가있었습니다. 각 책마다 하나씩, 알파벳 순서로 (아마 제목별로) 정렬되어 있습니다. 이는 “비 클러스터형 인덱스”에 해당 합니다. 이 카드 카탈로그는 계층 구조로 구성되어 각 드로어에 포함 된 카드 범위 ( Ka - Kl예 : “중간 노드”) 가 레이블로 표시됩니다 . 다시 한번, 당신은 당신의 책을 찾을 때까지 드릴 만에 것 있습니다 (즉, “리프 노드”)를 발견하면 경우에, 당신은 책 자체가 없습니다클러스터 된 색인에서 실제 책을 찾을 수있는 색인 번호 (DDS #).

물론 사서가 모든 카드를 복사하여 별도의 카드 카탈로그에서 다른 순서로 정렬하는 것을 막을 수는 없습니다. 일반적으로 이러한 카탈로그는 저자 이름별로 정렬되고 하나는 제목별로 정렬됩니다. 원칙적으로 원하는만큼 “비 클러스터형”인덱스를 가질 수 있습니다.


답변

클러스터형 및 비 클러스터형 인덱스의 일부 특성을 아래에서 찾으십시오.

클러스터형 인덱스

  1. 클러스터형 인덱스는 SQL 테이블에서 행을 고유하게 식별하는 인덱스입니다.
  2. 모든 테이블에는 정확히 하나의 클러스터형 인덱스가있을 수 있습니다.
  3. 둘 이상의 열을 포함하는 클러스터형 인덱스를 만들 수 있습니다. 예를 들면 다음과 같습니다 create Index index_name(col1, col2, col.....)..
  4. 기본적으로 기본 키가있는 열에는 이미 클러스터 된 인덱스가 있습니다.

비 클러스터형 인덱스

  1. 비 클러스터형 인덱스는 단순한 인덱스와 같습니다. 그들은 단지 빠른 데이터 검색을 위해 사용됩니다. 고유 한 데이터가 있는지 확실하지 않습니다.

답변

매우 간단하고 기술적이지 않은 규칙은 클러스터 된 인덱스가 일반적으로 기본 키 (또는 적어도 고유 열)에 사용되고 클러스터되지 않은 다른 상황 (외래 키일 수 있음)에 사용된다는 것입니다. . 실제로 SQL Server는 기본적으로 기본 키 열에 클러스터형 인덱스를 만듭니다. 학습 한 바와 같이, 클러스터형 인덱스는 디스크에서 데이터가 물리적으로 정렬되는 방식과 관련이 있으므로 대부분의 상황에 적합한 종합적인 선택입니다.


답변

클러스터형 인덱스

클러스터 된 인덱스는 테이블에서 DATA의 물리적 순서를 결정하므로 테이블에는 하나의 클러스터 된 인덱스 만 있습니다.

  • dictionary “다른 인덱스가 필요하지 않습니다. 단어에 따라 이미 인덱스되어 있습니다.

비 클러스터형 인덱스

비 클러스터형 인덱스는 책의 인덱스와 유사하며 데이터는 한 곳에 저장됩니다. 인덱스가 다른 위치에 저장되고 인덱스에 데이터의 저장 위치에 대한 포인터가 있으므로 테이블에 클러스터되지 않은 인덱스가 둘 이상 있습니다.

  • 화학 책”은 챕터 위치를 가리키는 별도의 색인이 있으며 “END”에는 공통 WORDS 위치를 가리키는 다른 색인이 있습니다.