MSSQL
[MSSQL] INDEX REBUILD 및 조각화 진단
minies
2024. 9. 25. 23:46
반응형
모든 DB가 공통적으로 DML(UPDATE, DELETE, INSERT) 작업이 많이 발생하면 인덱스 조각화가 발생하며, DB 성능이 떨어지고 비효율적으로 공간을 사용하게 된다. 그래서 인덱스 조각화에 따라 INDEX REBUILD 를 주기적으로 해주어야 한다. (enterprise가 아니라면.. online 중 rebuild 가 안되기 때문에 운영중에는.. 하기 쉽지 않다..) online 중으로 하게 되더라도 보통 운영 중인 DB는 부하가 갈 수 있고, 소요시간도 오래걸리기 때문에 사용량이 적은 시간에 진행해야 한다.
※ 인덱스 조각화 진단
-- 특정 TABLE 진단
SELECT
dbschemas.name AS SchemaName,
dbtables.name AS TableName,
dbindexes.name AS IndexName,
indexstats.avg_fragmentation_in_percent
FROM
sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('스키마.테이블_이름'), NULL, NULL, 'LIMITED') AS indexstats
JOIN sys.indexes AS dbindexes ON indexstats.object_id = dbindexes.object_id AND indexstats.index_id = dbindexes.index_id
JOIN sys.tables AS dbtables ON dbindexes.object_id = dbtables.object_id
JOIN sys.schemas AS dbschemas ON dbtables.schema_id = dbschemas.schema_id
ORDER BY
indexstats.avg_fragmentation_in_percent DESC;
-- 전체 DB 진단
SELECT
dbschemas.name AS SchemaName,
dbtables.name AS TableName,
dbindexes.name AS IndexName,
indexstats.avg_fragmentation_in_percent
FROM
sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS indexstats
JOIN sys.indexes AS dbindexes ON indexstats.object_id = dbindexes.object_id AND indexstats.index_id = dbindexes.index_id
JOIN sys.tables AS dbtables ON dbindexes.object_id = dbtables.object_id
JOIN sys.schemas AS dbschemas ON dbtables.schema_id = dbschemas.schema_id
WHERE
dbindexes.index_id > 0 -- 인덱스가 있는 경우
ORDER BY
indexstats.avg_fragmentation_in_percent DESC;
※ REBUILD 기준은 운영 중인 DB 마다 다름
- 10% ~ 30% 조각화가 있는 경우에는 인덱스를 Reorganize하여 처리하는 것이 일반적.
- Reorganize는 시스템 리소스를 적게 사용하고, 온라인에서 실행 가능
인덱스 Rebuild 과정
인덱스를 재구성하는 방법: 온라인(Online)과 오프라인(Offline)
온라인 모드에서는 테이블이 잠기지 않아도 되지만, 오프라인 모드에서는 테이블에 LOCK이 발생한다.
1. 인덱스 용량 산정
-- 데이터베이스 전체 공간 사용량 확인
EXEC sp_spaceused;
-- 특정 테이블의 공간 사용량 확인
EXEC sp_spaceused '[스키마].[테이블_이름]';
2. 특정 테이블의 인덱스를 재구성하는 SQL
-- 오프라인 인덱스 Rebuild
ALTER INDEX [인덱스_이름] ON [스키마].[테이블_이름] REBUILD;
-- 모든 인덱스 오프라인 Rebuild
ALTER INDEX ALL ON [스키마].[테이블_이름] REBUILD;
-- 온라인 인덱스 Rebuild (Enterprise Edition에서만 가능)
ALTER INDEX [IndexName] ON [TableName]
REBUILD
WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON, ONLINE = ON, STATISTICS_NORECOMPUTE = ON, MAXDOP = 4);
-- 모든 인덱스 온라인 Rebuild
ALTER INDEX ALL ON [TableName]
REBUILD
WITH (FILLFACTOR = 90, SORT_IN_TEMPDB = OFF, ONLINE = OFF, STATISTICS_NORECOMPUTE = OFF, MAXDOP = 2);
- FILLFACTOR = 80: 페이지에 데이터를 채울 때 80%만 채움.
- SORT_IN_TEMPDB = ON: 정렬 작업을 TempDB에서 수행.
- ONLINE = ON: 인덱스 리빌드를 온라인으로 실행 (테이블 잠금을 최소화).
- STATISTICS_NORECOMPUTE = ON: 리빌드 중에 통계를 다시 계산하지 않음.
- MAXDOP = 4: 병렬 처리를 4개의 CPU로 제한.
※ REBUILD 하면서 LOG 파일 용량 산정 후 LOG 백업 수행
-- 로그 파일의 사용률 확인
DBCC SQLPERF(LOGSPACE);
LOG 백업을 돌려주지 않으면 자동증설로 되어 있을 경우 로그 파일이 계속 커진다...
로그파일은 한번 커지면 줄이기 쉽지 않기 때문에 주의해서 관리 필요
-- 로그 백업
BACKUP LOG [데이터베이스_이름]
TO DISK = 'C:\Backup\LogBackup.bak'
WITH INIT;
반응형