[SQL Server]안 쓰이는 인덱스를 찾아보자!

Updated:

이 인덱스 지워도 될까?

오랫동안 운영 되고있는 SQL SERVER를 열어보면

상당히 많은 인덱스가 있다.

처음 프로젝트를 진행할때 만들었던 인덱스 부터,

중간중간 느린 쿼리로 인해 튜닝시 만들었던 인덱스도 있고,

아직 DB를 잘 모르는 누군가가 만들어놓고 안 지운 인덱스도 있을것이다.

실제로 1년전쯤 보았던 어떤 테이블은 약 40개의 인덱스가 있는것도 보았다.

MS SQL SERVER의 경우 한개의 테이블에 999개까지 인덱스를 만들수 있고,

꼭 필요한 인덱스는 당연히 필요시 생성해야한다.

그러나,

인덱스에 해당하는 컬럼이 UPDATE, INSERT가 일어나면 그 컬럼과 관련된 인덱스를

변경하는 비용이 발생하고, 이로인해 DB에 꽤 많은 부담을 주게 된다.

그러면 사용하지 않는 인덱스는 어떻게 찾아볼수 있을까?

MS SQL SERVER는 sys.dm_db_index_usage_stats DMV에서 해당 내용을 찾아볼수 있다.

(중요 : DMV는 DB를 내릴경우 초기화 되므로 DB를 올리고 바로 조회한다면,

당연히 인덱스를 모두 사용하지 않는다고 나올것이다. 오랜기간 사용중인 DB에서 참고하기 바란다.)

이 DMV에서는 인덱스별 user_seeks, user_scans, user_lookups 컬럼이 있는데

이 컬럼이 모두 사용량이 0이라면 이 인덱스는 사용하지 않는다.

(물론 DB를 올리고 그 후의 사용량이다.)

따라서 아래와 같은 쿼리를 통해 인덱스 사용량을 알 수 있다.

SELECT TOP 10

DatabaseName = DB_NAME()

,TableName = OBJECT_NAME(s.[object_id])

,IndexName = i.name

,user_updates

,system_updates

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]

AND s.index_id = i.index_id

WHERE s.database_id = DB_ID()

AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0

AND user_seeks = 0

AND user_scans = 0

AND user_lookups = 0

AND i.name IS NOT NULL

ORDER BY user_updates DESC --인덱스 UPDATE 기준 정렬

[결과]

운영시 인덱스가 과도하게 많을때 이를 참조하여 불필요 인덱스를 파악할 수 있다.

(물론 인덱스를 DROP할때는 많은 주의가 필요하다.)