SQL Server의 DMV 또는 쿼리 계획에 누락 된 인덱스 요청이없는 이유는 무엇입니까? 누락 된 인덱스 DMV

쿼리 속도가 매우 느린 SQL Server 데이터베이스가 있으며 많은 잠금 및 차단 기능이 있습니다.

누락 된 인덱스 DMV 및 쿼리 계획을 볼 때 제안 사항이 없습니다.

왜 그런 겁니까?



답변

누락 된 인덱스 요청이없는 데는 여러 가지 이유가 있습니다!

몇 가지 이유를 자세히 살펴보고 기능의 일반적인 제한 사항에 대해서도 이야기합니다.

일반 제한

먼저, 누락 된 인덱스 기능의 한계 :

  • 인덱스에서 열을 사용할 순서를 지정하지 않습니다.

이 Q & A에서 언급 한 것처럼 SQL Server는 누락 된 인덱스 요청에서 키 열 순서를 어떻게 결정합니까? 인덱스 정의의 열 순서는 Equal vs Inequality 술어와 테이블의 열 서수 위치에 의해 결정됩니다.

선택성에 대한 추측은 없으며 더 나은 주문이 가능합니다. 그것을 알아내는 것이 당신의 일입니다.

특수 인덱스

누락 된 인덱스 요청에는 다음과 같은 ‘특별한’인덱스도 포함되지 않습니다.

  • 클러스터
  • 거르는
  • 분할
  • 압축
  • XML로
  • 공간적
  • Columnstore-d
  • 인덱싱 된 뷰

어떤 열이 고려됩니까?

누락 된 인덱스 키 열은 다음과 같은 결과 필터링에 사용되는 열에서 생성됩니다.

  • 가입
  • WHERE 절

누락 된 색인 포함 열은 다음과 같이 쿼리에 필요한 열에서 생성됩니다.

  • 고르다
  • GROUP BY
  • 주문

자주 주문하더라도 그룹화하거나 그룹화하는 열이 주요 열로 유용 할 수 있습니다. 이것은 제한 중 하나로 돌아갑니다.

  • 인덱싱 구성을 미세 조정하지는 않습니다.

예를 들어 LastAccessDate에 인덱스를 추가하면 정렬 (및 디스크 유출)이되지 않아도이 쿼리는 누락 된 인덱스 요청을 등록하지 않습니다.

SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;

견과류

위치에 대한이 그룹화 쿼리도 없습니다.

SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location

견과류

그다지 도움이되지 않습니다!

그래,하지만 아무것도 아닌 것보다 낫다. 울부 짖는 아기와 같은 누락 된 색인 요청을 생각하십시오. 문제가 있다는 것을 알고 있지만 그 문제가 무엇인지 알아내는 것은 성인의 책임입니다.

그래도 왜 내가 없는지 말해주지 않았지만 …

긴장을 풀어 라. 우리는 거기에 도착하고있다.

추적 플래그

TF 2330 을 사용하면 누락 된 인덱스 요청이 기록되지 않습니다. 이 기능을 활성화했는지 확인하려면 다음을 실행하십시오.

DBCC TRACESTATUS;

인덱스 재 구축

인덱스다시 작성 하면 누락 된 인덱스 요청이 지워집니다. 따라서 Hi-Ho-Silver-Away는 모든 인덱스를 재 구축하기 전에 조각화의 두 번째로 몰입 할 때마다 매번 삭제하는 정보에 대해 생각하십시오.

어쨌든 인덱스 조각 모음이 도움이되지 않는 이유 에 대해 생각할 수도 있습니다 . 당신이 사용하지 않는 Columnstore을 .

인덱스 추가, 제거 또는 비활성화

인덱스를 추가, 제거 또는 비활성화하면 해당 테이블에 대한 누락 된 인덱스 요청이 모두 지워집니다. 동일한 테이블에서 여러 인덱스 변경을 수행하는 경우 변경하기 전에 모두 스크립팅해야합니다.

사소한 계획

계획이 간단하고 인덱스 액세스 선택이 분명하고 비용이 충분히 낮 으면 사소한 계획을 얻게됩니다.

이는 효과적으로 옵티마이 저가 결정할 비용 기반 결정이 없음을 의미합니다.

비아 폴 화이트 :

사소한 계획 변경으로 혜택을 얻을 수있는 쿼리 유형에 대한 세부 정보는 일반적으로 조인, 하위 쿼리 및 부등식 술어와 같은 것이 일반적으로 이러한 최적화를 방해합니다.

계획이 사소한 경우 추가 최적화 단계를 탐색하지 않고 누락 된 인덱스를 요청하지 않습니다 .

이 쿼리와 계획 의 차이점을 확인하십시오 .

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);

견과류

첫 번째 계획은 사소한 것이며 요청이 표시되지 않습니다. 버그로 인해 누락 된 인덱스가 쿼리 계획에 나타나지 않는 경우가 있습니다. 그러나 일반적으로 누락 된 인덱스 DMV에보다 안정적으로 기록됩니다.

SARGability

인덱스가 있어도 옵티마이 저가 인덱스를 효율적으로 사용할 수없는 술어는 로그되지 않을 수 있습니다.

일반적으로 SARGable이 아닌 것은 다음과 같습니다.

  • 함수로 감싸 진 열
  • 열 + SomeValue = SomePredicate
  • 열 + AnotherColumn = SomePredicate
  • 열 = @Variable 또는 @Variable IS NULL

예 :

SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;


SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000


SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000


DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
      OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;

이러한 쿼리 중 누락 된 인덱스 요청은 등록하지 않습니다. 이에 대한 자세한 내용은 다음 링크를 확인하십시오.

당신은 이미 괜찮은 색인을 가지고 있습니다

이 색인을 보자 :

CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);

이 쿼리에는 문제가 없습니다.

SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND   p.CreationDate < '20181231'
AND   p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;

계획은 간단합니다.

견과류

그러나 주요 키 열은 덜 선택적인 술어를위한 것이기 때문에 다음과 같이 더 많은 작업을 수행하게됩니다.

‘게시물’표. 스캔 카운트 13, 논리적 읽기 136890

인덱스 키 열 순서를 변경하면 작업이 훨씬 줄어 듭니다.

CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);

견과류

그리고 훨씬 적은 읽기 :

‘게시물’표. 스캔 횟수 1, 논리적 읽기 5

SQL Server에서 인덱스 생성

경우에 따라 SQL Server는 인덱스 스풀을 통해 즉석에서 인덱스를 만들도록 선택합니다. 인덱스 스풀이 있으면 누락 된 인덱스 요청이 없습니다. 인덱스를 직접 추가하는 것은 좋은 생각이지만 SQL Server를 사용하여 계산할 수는 없습니다.

견과류


답변