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


14

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

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

왜 그런 겁니까?

답변:


17

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

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

일반 제한

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

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

이 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를 사용하여 계산할 수는 없습니다.

견과류

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.