자주 쓰는 쿼리 - Index 사용량 조회
테이블 조회 효율을 위해 인덱스를 생성하여 사용하는 것은 당연하다.
하지만 시간이 지나고 업무 계획의 방향성이 바뀌다보면, 이렇게 생성하여 사용하던 인덱스들 중 사용하지 않게 되는 인덱스가 생길 수 있다.
이렇게 사용하지 않는 인덱스를 한번씩 정리를 해주게 된다면, 테이블의 DML작업에 대해 효율이 조금이나마 올라갈 수 있게 되는데, 이럴 때 도움이 될 만한 인덱스 사용량 조회 쿼리에 대해서 한번 소개해보도록 한다.
Query
인덱스 사용량을 조회하는 쿼리는 아래와 같다.
use [DATABASE NAME]
select db_name(s.database_id) as database_name,
object_name(s.object_id) as table_name,
i.name as index_name,
s.*
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 object_name(s.object_id) = '[TABLE NAME]'
order by table_name, index_name
특정 데이터베이스의 특정 테이블에 대한 인덱스 사용량을 조회하는 쿼리이다.
해당 데이터베이스의 모든 테이블에 대해 인덱스를 조회하고 싶다면, [TABLE NAME]이 들어가는 조건을 제외하고 조회하면 된다.
위 쿼리에서 알 수 있는 정보들 중 몇가지 중요 정보에 대해서 간단히 소개해보도록 하겠다.
index_id - 인덱스의 종류 구분
index_id는 크게 3가지로 나눌 수 있다.
- 0 : Heap Table
- 1 : Clustered Index
- 2~255 : Index
먼저 0 : Heap Table이란, 클러스터 인덱스를 생성하지 않아 데이터의 저장이 Heap으로 구성되어있는 테이블을 말한다. 인덱스를 생성 한 것이 아니다보니 Index Name도 따로 없다.
그 다음으로는 1 : Clustered Index 이다.
클러스터 인덱스는 데이터를 지정키에 맞게 물리적으로 순서대로 저장한다는 것은 다들 알 것이다.
하나의 테이블에 한개밖에 가질 수 없는 인덱스이다. 꼭 PK가 아니여도 클러스터 인덱스 일 수 있다.
위에서 알 수 있듯, 0과 1의 ID값은 공존 할 수 없다.
마지막으로는 2~255 : 일반적인 Index 이다.
우리가 제일 많이 생성하고 인덱스 사용량이 궁금한 것은 대체로 이 범위에 들어가는 인덱스 일 것이다.
PK가 클러스터 인덱스가 아닐 경우 해당 값에 포함 될 수 있다.
index 사용량 조회
사용자의 인덱스 사용은 크게 4가지로 나누어진다. USER_SEEKS, USER_SCANS, USER_LOOKUPS, USER_UPDATES 이렇게 4가지이다.
아래의 내용은 Index사용량 조회 쿼리를 해당 데이터베이스의 모든 테이블에 대해서 조회해 본 내용이다.
하나의 테이블에 여러가지 인덱스가 생성되어 있는 모습을 확인 할 수 있다.
이 중 USER_SEEKS / USER_SCANS 의 경우는 해당 인덱스가 사용되어 조회 된 건수를 뜻한다. 일반적인 우리의 인덱스 사용이다.
USER_LOOKUPS는 무엇일까? 자세히보면 Index_ID = 1 즉 클러스터 인덱스에만 건수가 올라가 있는 모습을 볼 수 있다.
lookup의 경우는 key값을 가지고 해당 데이터를 찾아가는 과정인데, MsSQL의 인덱스 구조는 Clustered Index의 값을 Index의 키 값으로 가지고 있다.
그래서 인덱스를 사용하여 데이터를 찾아가게 되면 Key Lookup 과정이 발생 하여, 클러스터 인덱스를 lookup하여 데이터를 조회하게 된다.
즉, USER_LOOKUPS는 다른 인덱스를 통해 클러스터 인덱스의 key값으로 한번더 조회 된 값이라고 생각하면 편하다.
만약 클러스터 인덱스가 없을경우 Heap Table로 구성되어 RID값을 키 값으로 가지게되어 RID Lookup 과정이 발생하게 된다.
USER_UPDATES의 경우 쿼리 별 인덱스 업데이트 수 이다.
delete, update, insert 모두 포함이 되는데, 중요한 것은 쿼리 별 이라는 것이다. 한 동작의 dml 쿼리에 대해 1000건이 입력되어도 USER_UPDATES는 1건이 증가된다.
index 미사용
인덱스 미사용이란 무엇일까?
너무나 당연하겠지만 위에서 소개한 USER_SEEKS, USER_SCANS, USER_LOOKUPS의 3개의 컬럼 값이 0일 경우를 뜻한다.
해당 컬럼들의 값이 0일 경우 해당 인덱스에 삭제를 고려해 봐도 좋을거라 생각한다.
Related Posts
동적 관리 뷰 - SYS.DM_DB_INDEX_USAGE_STATS
'DATABASE > MsSQL' 카테고리의 다른 글
[MsSQL] 테이블 정의서 만들기 - 쿼리로 추출하기 (0) | 2024.03.26 |
---|---|
[MsSQL] Clustered 연구 노트 - 1. Heap Table 구조 파헤치기 (Page, Index) (0) | 2024.03.12 |
[MsSQL] Database Backup이란? - Full / Differential / Log Backup (0) | 2024.02.24 |
[MsSQL] 모든 DB에 한번 쿼리 던지기 / DB 모를 때 (SP_MSFOREACHDB 활용하기) (0) | 2024.02.13 |
[MsSQL] Database 복구 모델 - Simple, Full (단순 모델, 전체 모델) (0) | 2023.10.16 |
[MsSQL] OUTPUT - Update 사용 시, 변경 전/후 행 반환하기 (deleted/inserted) (0) | 2023.09.07 |
[MSSQL] 커서(CURSOR) - 행(ROW) 단위 처리의 사용 법 (0) | 2023.09.06 |
[MsSQL] OUTPUT - Delete 사용 시, 삭제 된 행 반환하기 (deleted) (0) | 2023.09.05 |