2013-08-02 3 views
0

데이터베이스에 부모 자식 관계 인 테이블이 여러 개 있습니다. 예를 들면 :클러스터되지 않은 외래 키 인덱스 권장 사항

CREATE TABLE [dbo].[cntnr_header] 
(
    [cntnr_id]   [dbo].[uid]  NOT NULL, 
    CONSTRAINT [pk_cntnr_header] PRIMARY KEY CLUSTERED ([cntnr_id] ASC), 
); 

CREATE TABLE [dbo].[cntnr_content] 
(
    [cntnr_content_id] [dbo].[uid]  NOT NULL, 
    [cntnr_id]   [dbo].[uid]  NOT NULL, 
    CONSTRAINT [pk_cntnr_content] 
     PRIMARY KEY CLUSTERED ([cntnr_content_id] ASC), 
    CONSTRAINT [fk_cntnr_content_cntnr_header] 
     FOREIGN KEY ([cntnr_id]) 
     REFERENCES [dbo].[cntnr_header] ([cntnr_id]), 
); 

현재 당신이 테이블 cntnr_content에서 외래 키 cntnr_id에 인덱스가없는 볼 수 있습니다. 튜닝 마법사를 실행하고 실제로및 cntnr_id 테이블에 cntnr_content에 클러스터되지 않은 인덱스를 추가하는 것이 좋습니다. cntnr_content_id이 이미 클러스터 된 인덱스이기 때문에 나는 이것을 이해하지 못합니다. 왜 이런 지수를 추천할까요?

CREATE NONCLUSTERED INDEX [_dta_index_cntnr_content_7_821577965__K1_K2] ON [dbo].[cntnr_content] 
(
    [cntnr_content_id] ASC, 
    [cntnr_id] ASC 
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY] 

나는 아마이 표에 불과 cntnr_id에 비 클러스터형 인덱스를 추가해야한다고 생각합니다.

이 시나리오에 권장되는 방법이 있습니까? 나는 항상 이와 같은 관계로 특정 인덱스를 추가해야합니까?

많은 쿼리는 cntnr_id에이 두 테이블을 함께 결합하거나 cntnr_id을 지정하여 cntnr_content에서 선택을 수행합니다. 이것은 또한 업데이트/삭제 무거운 테이블입니다. 업데이트 및 삭제는 항상 기본 키 (cntnr_content_id)에서 수행됩니다.

+2

외래 키에 대한 색인이 유용 할 수 있지만 "항상"및 "절대로"와 같은 용어 사용에 대해서는 매우주의해야합니다. 이 유형의 경우에는 테이블 자체의 구조 나 테이블 간의 관계가 아니라 데이터 쿼리 방법에 따라 크게 달라집니다. –

+0

@AaronBertrand 일반적으로이 테이블의 쿼리 방법에 대해 설명하는 몇 가지 추가 정보가 추가되었지만 튜닝 관리자가 두 열 모두에서 클러스터되지 않은 인덱스를 제안하는 이유가 궁금합니다. –

+1

질문에 "이 시나리오에서이 외래 키의 인덱스가 유용할까요?" 대답은 "아마도 그렇습니다." 테스트가 필요합니다.질문이 "모든 외래 키의 인덱스가 항상 유용할까요?" 내 대답은 아니오 야. –

답변

2

클러스터 된 인덱스는 물리적으로 디스크에 이진 트리로 저장됩니다. 일반적으로 그들은 무거운 작업 부하를 읽으십시오.

일반적으로 외래 키를 사용하여 해당 테이블의 데이터에 액세스하므로 cntnr_content 테이블에서 클러스터되지 않은 인덱스를 사용하지 않는 것이 좋습니다.

이 경우 외래 키를 사용할 때 찾지 못하는 방식으로 데이터가 디스크 전체에 퍼지기 때문에 기본 키의 클러스터 된 인덱스는 유용하지 않습니다. 따라서 클러스터되지 않은 인덱스를 사용하는 것이 좋습니다.

클러스터되지 않은 인덱스로 변경하면 데이터베이스가 외래 키를 통한 조회에 더 적합한 디스크 포맷을 선택할 수 있습니다. 물론 그렇게하면 기본 키의 조회 속도에 영향을 미치므로 하나의 경우에는 속도가 더 빨라지지만 다른 경우에는 속도가 저하됩니다.

+1

글쎄, 나는 "클러스터되지 않은 인덱스로 변경"이라고 말하지 않을 것입니다 - 클러스터 된 인덱스는 다른 쿼리에 유용 할 수 있으며 IMHO를 제거해서는 안됩니다. 기존 인덱스를 제거하지 않고 클러스터되지 않은 인덱스를 추가 할 수 있습니다. –

+0

맞습니다. 다른 검색어에 유용 할 수 있습니다. 프로파일 러가 권장 사항에 도달하는 데 사용한 논리를 설명하는 중이었습니다. –

0

cntnr_id의 비 클러스터형 인덱스는 외래 키에 대한 것이므로 헤더 테이블에서 헤더를 삭제하려고 시도하면 테이블 스캔이 필요하지 않습니다.

또한 헤더로 찾는 기본 사용 사례입니다.

cntnr_content_id에서 클러스터되지 않은 색인 자체만으로는 의미가 없습니다. 클러스터 된 인덱스보다 좁기 때문에 둘 다 (클러스터 된 인덱스) (cntnr_id, cntnr_content_id)의 조합 된 비 클러스터형 인덱스가이 순서대로 포함될 수 있습니다.

+0

잘 cntnr_content_id에 의해 해당 테이블에 대해 수행 된 많은 업데이트/삭제가 있습니다. 나는 아직도이 경우에 유익 할 것이라고 생각할 것이다. –

+0

@ColeW 가능성이 낮습니다. 이는 CI의 첫 번째 열이며 CI는 실제로 업데이트되거나 삭제되어야하는 항목입니다. 테이블은 힙 또는 클러스터 된 인덱스라는 것을 알고 있습니까? 클러스터형 인덱스는 테이블과 별개의 것이 아닙니다. 테이블 데이터가 클러스터 된 인덱스 키와 리프의 키가 아닌 데이터를 기반으로 b-tree에서 구조화되는 방식을 설명합니다. 그런 다음 비 클러스터형 인덱스는 클러스터 된 인덱스 b- 트리의 힙 책갈피 또는 클러스터 된 인덱스 키를 참조하는 별도의 b- 트리입니다. –

관련 문제