인덱스를 작성할 때 INCLUDE 절을 사용하는 이유는 무엇입니까?
70-433 시험을 준비하는 동안 다음 두 가지 방법 중 하나로 커버리지 인덱스를 작성할 수 있다는 것을 알게 되었습니다.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
-- 또는 --
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
INCLUDE 조항은 나에게 생소하다.INCLUDE 절이 있는지 여부에 관계없이 커버리지수를 작성할 것인지 결정할 때 어떤 가이드라인을 제안하시겠습니까?
이 " " "에 WHERE/JOIN/GROUP BY/ORDER BY단, 의 컬럼목록에만 있습니다.SELECT은 '하다'를 입니다.INCLUDE.
INCLUDE절은 인덱스 트리가 아닌 맨 아래/리프 수준에서 데이터를 추가합니다.를 더 만듭니다.
INCLUDE columns인덱스의 키 열이 아니므로 순서가 매겨지지 않습니다.즉, 전술한 바와 같이 술어, 정렬 등에는 그다지 도움이 되지 않습니다.그러나 키 열에서 몇 줄의 나머지 조회가 있는 경우 유용합니다.
INCLUDE를 사용하여 하나 이상의 열을 비클러스터 인덱스의 리프 수준에 추가할 수 있습니다. 이렇게 하면 쿼리를 "커버링"할 수 있습니다.
직원의 ID, 부서 ID 및 성을 조회해야 한다고 가정합니다.
SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5
비클러스터된 인덱스가 있는 경우(직원)ID, 부서ID)는 특정 부서의 직원을 찾으면 실제 전체 직원 기록을 얻기 위해 "북마크 조회"를 수행해야 합니다. 단지 성 열을 얻기 위해서입니다.직원 수가 많으면 성능 면에서 상당히 비쌀 수 있습니다.
해당 성을 인덱스에 포함시킨 경우:
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(DepartmentID)
INCLUDE (Lastname, EmployeeID)
필요한 모든 정보를 비표준 인덱스의 리프 레벨에서 사용할 수 있습니다.비클러스터 인덱스에서 검색하여 특정 부서의 직원을 찾는 것만으로 필요한 모든 정보를 얻을 수 있으며 인덱스에서 발견된 각 직원의 북마크 검색이 필요하지 않게 되었습니다.-> 많은 시간을 절약할 수 있습니다.
물론 모든 비클러스터형 인덱스에 모든 열을 포함할 수는 없지만 "커버링"할 열이 하나 또는 두 개만 누락되어 있고 많이 사용되는 쿼리가 있는 경우 이러한 열을 적절한 비클러스터형 인덱스에 포함하면 매우 유용합니다.
이 논의는 중요한 점을 빠뜨리고 있습니다.문제는 "비키 열"을 인덱스 열로 포함할지 또는 포함 열로 포함할지 여부가 아닙니다.
문제는 인덱스에 실제로 필요하지 않은 열을 포함하기 위해 포함 메커니즘을 사용하는 것이 얼마나 비싼가 하는 것입니다.(일반적으로 where-time의 일부가 아니지만 선택 항목에 포함되는 경우가 많습니다).그래서 항상 딜레마는 다음과 같습니다.
- id1, id2... idN에서만 인덱스 사용 또는
- id1, id2... idN에 col1, col2... colN 포함 인덱스 사용
여기서 id1, id2 ... idN은 제한에서 자주 사용되는 열이고 col1, col2 ... colN은 자주 선택되지만 일반적으로 제한에서는 사용되지 않습니다.
(이러한 모든 열을 인덱스 키의 일부로 포함하는 옵션은 (제한사항에서도 사용되지 않는 한) 항상 어리석은 것입니다. "키"가 변경되지 않은 경우에도 인덱스를 업데이트하고 정렬해야 하므로 유지 비용이 항상 더 많이 들기 때문입니다.
옵션 1 또는 2를 사용하시겠습니까?
답변: 테이블이 거의 업데이트되지 않는 경우(대부분 삽입/삭제된 경우) 삽입/삭제 시 인덱스를 업데이트/소트해야 하므로 추가 오버헤드가 거의 없기 때문에 포함 메커니즘을 사용하여 일부 "핫 컬럼"을 포함하는 것이 비교적 저렴합니다(선택 시 자주 사용되지만 제한 시 자주 사용되지 않음).인덱스를 이미 업데이트하는 동안 몇 개의 추가 열을 저장하는 것과 관련이 있습니다.오버헤드는 인덱스에 다중 정보를 저장하는 데 사용되는 추가 메모리 및 CPU입니다.
포함 열로 추가할 것으로 생각하는 열이 자주 업데이트되는 경우(인덱스 키 열이 업데이트되지 않음) 또는 인덱스가 테이블의 복사본에 근접할 정도로 많은 경우 옵션 1을 사용하는 것이 좋습니다.또한 특정 include-column을 추가해도 성능 차이가 없는 것으로 판명된 경우 추가는 생략할 수 있습니다.
키(id1, id2 ... idN)의 같은 값당 평균 행 수도 어느 정도 중요할 수 있습니다.
인덱스의 포함 열로 추가된 열이 제한에 사용되는 경우:인덱스를 사용할 수 있는 한(index-key-columns에 대한 제한에 따라) SQL Server는 테이블 자체에서 비용이 많이 드는 대신 인덱스(leaf-node-values)에 대해 열 제한을 일치시킵니다.
기본 인덱스 열은 정렬되지만 포함된 열은 정렬되지 않습니다.이렇게 하면 인덱스를 유지하는 데 필요한 리소스를 절약할 수 있을 뿐 아니라 포함된 열의 데이터를 제공하여 쿼리를 처리할 수 있습니다.따라서 쿼리를 포함하려면 검색 기준을 적용하여 인덱스의 정렬된 열에 행을 찾은 다음 검색 데이터가 아닌 정렬되지 않은 열을 추가로 "포함"할 수 있습니다.인덱스 유지보수의 정렬 및 조각화 양을 줄이는 데 확실히 도움이 됩니다.
「」를 선택하는 .INCLUDE키 내의 그 컬럼이 필요하지 않은 경우 키 오버랩이 문서화됩니다.따라서 향후 인덱스 진화가 훨씬 쉬워집니다.
예를 들면 다음과 같습니다.
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
이 인덱스는 쿼리가 다음과 같은 경우에 가장 적합합니다.
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
칸은 .INCLUDE주요 부품에 추가 혜택을 받을 수 있는지 확인합니다. 두 모두 실제로는 ' 낫다'를 합니다.col2이치노
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
AND col2 = ...
SELECT TOP 1 col2, col3
FROM MyTable
WHERE col1 = ...
ORDER BY col2
그렇지 않다고 가정해 봅시다.col2 INCLUDE이 조항은 지수의 트리 부분에 해당 조항이 있으면 아무런 이점이 없기 때문입니다.
몇 년 전으로 거슬러 올라가죠
다음 쿼리를 조정해야 합니다.
SELECT TOP 1 col2
FROM MyTable
WHERE col1 = ...
ORDER BY another_col
이 쿼리를 최적화하려면 다음 인덱스가 좋습니다.
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2)
테이블에 이미 있는 인덱스를 체크하면 이전 인덱스가 그대로 있을 수 있습니다.
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
?Col2 ★★★★★★★★★★★★★★★★★」Col3는 인덱스 트리의 일부가 아니므로 읽기 인덱스 범위를 좁히거나 행을 정렬하는 데 사용되지 않습니다. 더 넣어도 합니다.another_column키 까지('뒤에)col1될 위험은 : ) 파손될 위험은 거의 없습니다.
DROP INDEX idx1 ON MyTable;
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2, Col3);
그 지수는 더 커질 것이고, 이것은 아직 위험이 있지만, 일반적으로 새로운 지수를 도입하는 것보다 기존 지수를 연장하는 것이 더 낫다.
가 INCLUDE , , , , , , , , , , , , , , 를 으로써, 알 수.another_col직직 Col1.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
''를 추가하면 어떻게 요?another_colCol1 ★★★★★★★★★★★★★★★★★」Col2는 문제가 른?
밖에도 '이 .INCLUDEvs. 키 컬럼을 추가할 경우 해당 컬럼을 테이블에서 가져오지 않도록 합니다.다만, 저는 문서화의 측면을 가장 중요하게 생각합니다.
질문에 답하려면:
INCLUDE 조항이 있는지 없는지를 결정할 때 어떤 지침을 제안하겠습니까?
할 수 을 에 .INCLUDE절을 클릭합니다.
하면 다른 " " " " " " " " " " " ) 。order by또는 읽기 인덱스 범위를 좁힐 수 있기 때문에) 키에 추가합니다.
이에 대한 자세한 내용은 여기를 참조하십시오.
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes
그 이유(지수의 리프 레벨의 데이터 포함)는 잘 설명되었다.이에 대해 신경 쓰는 이유는 쿼리를 실행할 때 추가 컬럼이 포함되어 있지 않은 경우(SQL 2005의 새로운 기능) SQL Server는 클러스터 인덱스로 이동하여 추가 컬럼을 가져와야 하기 때문입니다.이러한 컬럼은 시간이 더 오래 걸리고 SQL Server 서비스인 디스크에는 부하가 더 많이 걸리기 때문입니다.새로운 데이터 페이지가 메모리에 로드되면 메모리(구체적으로는 메모리 캐시)가 추가되어 더 자주 필요한 다른 데이터가 버퍼 캐시에서 밀려날 수 있습니다.
이미 주어진 답변에서 볼 수 없는 또 다른 고려사항은 포함된 열이 varchar(max)와 같이 인덱스 키 열로 허용되지 않는 데이터 유형일 수 있다는 것입니다.
이렇게 하면 커버링 인덱스에 이러한 열을 포함할 수 있습니다.최근 SELECT에 많은 열이 있는 nHibernate 생성 쿼리를 유용한 인덱스와 함께 제공하기 위해 이 작업을 수행해야 했습니다.
인덱스 정의에 삽입된 모든 열의 총 크기에는 제한이 있습니다.하지만 이렇게 넓은 인덱스를 만들 필요는 없었습니다.더 큰 장점은 열을 포함하는 하나의 인덱스로 더 많은 쿼리를 처리할 수 있다는 것입니다. 열을 특정 순서로 정의할 필요가 없기 때문입니다.에 대해 인덱스 내의 인덱스로 생각하십시오.예를 들어 Store가 있습니다.ID(스토어 위치)ID는 선택성이 낮습니다.즉, 각 스토어가 많은 고객과 관련되어 있으며, 다음으로 고객의 통계 데이터(LastName, FirstName, DOB):이러한 컬럼을 이 순서로 인라인(StoreID, LastName, FirstName, DOB)하는 경우 Store를 알고 있는 고객만 효율적으로 검색할 수 있습니다.아이디와 성.
한편, Store에서 인덱스 정의ID 및 LastName, FirstName, DOB 열을 포함하면 기본적으로 스토어에서 두 가지 검색 색인 술어를 수행할 수 있습니다.ID를 지정한 다음 포함된 열 중 하나에서 술어를 찾습니다.이렇게 하면 Store로 시작하는 한 가능한 모든 검색 순서를 커버할 수 있습니다.아이디
언급URL : https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index
'source' 카테고리의 다른 글
| sql 쿼리: 두 테이블 간의 차이를 반환합니다. (0) | 2023.04.07 |
|---|---|
| 데이터를 다른 테이블로 복사 (0) | 2023.04.07 |
| 레코드가 존재하는지 여부를 확인하는 가장 빠른 방법 (0) | 2023.04.07 |
| Angular JS 스타일 가이드 - 토드 모토 vs 존 파파 vs 밍코 게체프 (0) | 2023.04.02 |
| 부스트에 의한 JSON의 시리얼화 및 시리얼화 해제 (0) | 2023.04.02 |