기존 인덱스가 새 인덱스의 모든 열을 포함 할 때이 새 인덱스를 생성하면 성능이 크게 향상되는 이유는 무엇입니까?


19

Log 및 LogItem 테이블이 있습니다. 둘 다에서 일부 데이터를 가져 오기 위해 쿼리를 작성 중입니다. 수천 개가 Logs있으며 각각 Log최대 125 개를 가질 수 있습니다LogItems

문제의 쿼리가 복잡하므로 건너 뛰고 있습니다 (누군가 생각하면 게시 할 수 있다고 생각하면) SSMS Estimated Query 계획을 실행하면 새로운 비 클러스터 색인이 성능을 최대 100 % 향상시킬 것이라고 말했습니다. .

Existing Index: Non-clustered
Key Colums (LogItem): ParentLogID, DateModified, Name, DatabaseModified

Query Plan Recommendation
CREATE NONCLUSTERED INDEX [LogReportIndex]
ON [dbo].[LogItem] ([ParentLogID],[DatabaseModified])

재미있게, 나는이 새로운 색인을 만들고 쿼리를 실행했으며 놀랍게도 10 초 전에는 쿼리가 실행되기까지 ~ 1 초가 걸렸습니다.

기존 인덱스가이 새 쿼리를 처리한다고 가정했기 때문에 새 쿼리에 사용 된 열에 만 새 인덱스를 생성하면 성능이 향상되는 이유는 무엇입니까? 내 where절에 사용 된 각 고유 한 열 조합에 대한 색인이 있어야합니까 ?

참고 : SQL Server가 내 결과를 캐싱하고 있기 때문에 인덱스를 생성하기 전에 약 25-30 번 쿼리를 실행했으며 인덱스 이후 10-15 초가 걸렸습니다. 이하.


비 클러스터형 인덱스를 추가로 만들기 전에 실제 실행 계획 에서 인덱스 사용에 대해 무엇을 보여 주었습니까?
Thomas Stringer

100 % 개선 된 성능은 무엇입니까?

@Shark 좋은 질문입니다. 잘 모르겠습니다. 이것이 첫 번째 성능 디버깅 상황입니다. 앞으로도 그 점을 확실하게 다룰 것입니다. 그것은 '누락 된 색인'이라고 말했고 어떤 필드를 말했습니까.

@JeffO SSMS의 말 : "쿼리 프로세서는 다음 인덱스를 구현하면 쿼리 비용을 100 % 향상시킬 수 있다고 추정합니다."

답변:


21

인덱스의 열 순서가 중요합니다. 필터링에 인덱스의 열 1과 4가 필요한 경우 인덱스가 도움이되지 않습니다. 첫 번째 N 개의 연속 열로 필터링 할 때만 유용합니다.

인덱스가 트리이기 때문입니다. 및의 column3 = something다른 값에 속하는 다른 모든 곳에 흩어져 있기 때문에 트리의 모든 노드를 효율적으로 선택할 수 없습니다 . 당신이 안다면 및 뿐만 아니라, 트리의 오른쪽 지점을 찾는 것은 더 생각할 필요 없다.column1column2column1column2


그러면 일반적으로 해당 테이블에 도달 할 "where"절 세트당 하나의 색인이 필요하다고 가정하는 것이 안전합니까?

한 번만 인덱스를 올바른 순서로 사용했는지 확인하여 다른 사람의 쿼리를 크게 가속화했습니다.

1
@Nate 광범위하게 그렇습니다. 일부 where가 겹칠 수 있으므로 여러 가지를 잘 다루는 색인이있을 수 있습니다 where. 또는 where특정 열의 인덱싱이 도움이되지 않기 때문에 절의 일부를 무시할 수 있습니다 (선택성이 낮음). 그러나 광범위하게 그렇습니다.

@Nate 필요 이상의 색인을 원하지 않습니다. SQL이 유지 관리해야하는 각 인덱스는 자체 오버 헤드를 추가합니다. 기존 색인의 첫 번째 N 열과 일치하도록 WHERE 절을 재정렬 할 수 있으면 추가 색인을 추가하지 않고도 매우 가깝게 얻을 수 있습니다.
그 척 가이

1
@ChuckBlumreich where절의 열 순서는 중요하지 않습니다. 서버는 항상 기존 인덱스를 최대한 활용하도록 정렬합니다. 모든 필수 where열을 첫 번째 열로 포함하는 인덱스가 있는지에 대한 질문 일뿐 입니다.

12

첨단 인덱스가 중요한 것입니다.

쿼리가 인덱스의 최첨단에 의해 "포함"되어 있으면 효율적입니다. 데이터베이스 인덱스는 일반적으로 B-Tree로 구현되며 B-Tree의 구조에 따라 특정 순서로 검색을 수행해야하므로 복합 인덱스의 필드 순서가 중요합니다.

"구멍"이있는 경우 (예 : ParentLogIDDatabaseModified에서 검색 하지만 인덱스 만있는 경우) 인덱스 {ParentLogID, DateModified, Name, DatabaseModified}{ParentLogID}일부만 효율적으로 사용할 수 있습니다.

(참고 : 일부 DBMS는 {DatabaseModified}"스킵 스캔"을 통해이 부분을 활용할 수 있지만, DBMS가 일반 인덱스 액세스보다 훨씬 덜 효율적이라고하더라도) .


그래서 내가 가지고 Columns (a, b, c, d, e, f)있고 대부분의 쿼리가 좋은 ... WHERE A IN(...) AND B = 3인덱스 인 인덱스 Index(a,b,c,d)이지만 ... WHERE A IN (...) AND D = 5, 내가 만든 새 인덱스가 Index(a,d)성능을 크게 향상 시키는 이유는 무엇 입니까?

8
@Nate-맞습니다. 전화 번호부처럼 생각하십시오. 누군가의 이름 만 알고 있다면 성, 이름
JNK
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.