Physical
[MSSQL] DB내의 모든 테이블 및 인덱스 현황
Zac
2021. 7. 30. 11:08
근 5년만에 다시 잡은 MSSQL..
기존 현황 조회에 사용하던건 한방이 아니기도 하고 예전 메타뷰들을 많이 사용해서
새롭게 한방 쿼리로 작성해보았다.
db_name부터 update_ymd까지가 테이블에 대한 정보이며
idx_type부터 idx_col_name까지가 해당 테이블의 개별 인덱스들에 대한 정보
테이블 정보만 조회하고자 할 경우 4번째 줄부터 시작하는 서브쿼리만 실행.
total_size_mb : 데이터 및 인덱스 포함 모든 크기
2nd_idx_cnt : 테이블데이터가 포함되어 있는 clustered index를 제외한 2차 인덱스들의 개수
2nd_idx_cnt : 테이블데이터가 포함되어 있는 clustered index를 제외한 2차 인덱스들의 크기
update_ymd : 테이블 데이터 마지막 변경일(insert,update,delete)
idx_type : 1(clustered), 2(non clustered)
idx_col_name : 복합 인덱스의 경우 컬럼 순서대로 콤마로 구분해서 대상 컬럼명 표시
last_user_use : insert나 update, delete가 아닌 조회에(scan, seek, lookup)에 사용된 마지막 일자
select a.db_name, a.schema_name, a.tbl_name, a.tbl_type, a.row_cnt, a.total_size_mb, a.[2nd_idx_cnt], a.[2nd_idx_size_mb], a.create_ymd, a.update_ymd
, b.idx_type, b.is_primary_key, b.is_unique, b.idx_size_mb, b.idx_name, b.last_user_use_ymd, b.idx_col_cnt, b.idx_col_name
from (
select db_name(db_id()) as db_name
, (select name from sys.schemas with(nolock) where schema_id = a.schema_id) as schema_name
, a.name as tbl_name
, case when min(b.index_id) = 0 then 'heap' else 'clustered' end as tbl_type
, sum(case when (b.index_id < 2) then b.row_count else 0 end) as row_cnt
, cast(sum(b.used_page_count) * 8.0 / 1024.0 as numeric(36, 2)) as total_size_mb
, sum(case when b.index_id > 1 then 1 else 0 end) as [2nd_idx_cnt]
, cast(sum(case when b.index_id < 2 then 0 else b.used_page_count end) * 8.0 / 1024.0 as numeric(36, 2)) as [2nd_idx_size_mb]
, convert(varchar(10), a.create_date, 120) as create_ymd
, convert(varchar(10), (select max(last_user_update) from sys.dm_db_index_usage_stats with(nolock) where object_id = a.object_id and database_id = db_id()), 120) as update_ymd
, db_id() as db_id
, a.schema_id
, a.object_id
from sys.tables a with(nolock)
join sys.dm_db_partition_stats b with(nolock) on a.object_id = b.object_id
group by a.schema_id, a.object_id, a.name, a.create_date
) a
left join (
select a.name as tbl_name
, b.type as idx_type
, b.is_primary_key
, b.is_unique
, b.index_id
, (
select sum(used_page_count)
from sys.dm_db_partition_stats with(nolock)
where object_id = b.object_id
and index_id = b.index_id
) idx_size_mb
, b.name as idx_name
, convert(varchar(10), case when isnull(c.last_user_seek, '1900-01-01') > isnull(c.last_user_scan, '1900-01-01')
and isnull(c.last_user_seek, '1900-01-01') > isnull(c.last_user_lookup, '1900-01-01') then isnull(c.last_user_seek, '1900-01-01')
when isnull(c.last_user_scan, '1900-01-01') > isnull(c.last_user_lookup, '1900-01-01') then isnull(c.last_user_scan, '1900-01-01')
else isnull(c.last_user_scan, '1900-01-01')
end
, 120
) as last_user_use_ymd
, (select count(*) from sys.index_columns with(nolock) where object_id = b.object_id and index_id = b.index_id) as idx_col_cnt
, stuff((
select ',' + bb.name
from sys.index_columns aa with(nolock)
join sys.columns bb with(nolock) on aa.object_id = bb.object_id
and aa.column_id = bb.column_id
where aa.object_id = b.object_id
and aa.index_id = b.index_id
order by aa.key_ordinal
for xml path('')
), 1, 1, ''
) as idx_col_name
, a.object_id
from sys.tables a with(nolock)
join sys.indexes b with(nolock) on a.object_id = b.object_id
and b.type in ('1', '2')
left join sys.dm_db_index_usage_stats c with(nolock) on b.object_id = c.object_id
and b.index_id = c.index_id
and c.database_id = db_id()
) b on a.object_id = b.object_id
order by a.total_size_mb desc, b.idx_col_name;