MS-SQL 2008 R2 데이터 최적화 방법
오래된 데이타 테이블 최적화 방법
🔹 1단계: 전체 테이블 데이터 정리 (아카이빙 및 불필요한 데이터 삭제)
📌 오래된 데이터를 분리하여 테이블 크기를 줄이기
1️⃣ 오래된 데이터가 많은 테이블 찾기
아래 SQL을 실행하면 **각 테이블의 데이터 개수(행 수)**를 확인할 수 있습니다.
SELECT t.name AS TableName, i.rows AS RowCounts
FROM sys.tables AS t
JOIN sys.sysindexes AS i ON t.object_id = i.id AND i.indid < 2
ORDER BY i.rows DESC;
👉 데이터 개수가 많고 오래된 테이블을 우선 정리해야 합니다.
2️⃣ 과거 데이터를 별도 테이블로 이동 (아카이빙)
예제: 10년 이상된 데이터를 아카이빙 테이블로 이동
SELECT * INTO sales_archive
FROM sales
WHERE order_date < '2014-01-01';
DELETE FROM sales
WHERE order_date < '2014-01-01';
✅ 효과
운영 테이블에서는 최근 데이터만 유지 → 속도 향상
과거 데이터는 별도 보관하여 필요할 때만 조회
🔹 2단계: 전체 테이블 인덱스 최적화
📌 30개 이상의 테이블을 하나씩 최적화하기 어렵기 때문에, 자동화 스크립트로 최적화 진행
1️⃣ 인덱스 단편화(조각화) 확인하기
SQL Server는 시간이 지나면 인덱스가 단편화되어 쿼리 속도가 느려질 수 있음
SELECT dbschemas.[name] AS 'Schema',
dbtables.[name] AS 'Table',
dbindexes.[name] AS 'Index',
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS indexstats
JOIN sys.tables dbtables ON dbtables.[object_id] = indexstats.[object_id]
JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id]
JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
AND indexstats.index_id = dbindexes.index_id
WHERE indexstats.database_id = DB_ID()
ORDER BY indexstats.avg_fragmentation_in_percent DESC;
👉 avg_fragmentation_in_percent 값이 30% 이상이면 인덱스를 재구성하는 것이 좋음
2️⃣ 전체 테이블의 인덱스 재구성 (자동화)
EXEC sp_MSForEachTable 'ALTER INDEX ALL ON ? REBUILD';
✅ 효과
조각난 인덱스를 최적화하여 검색 속도를 높임
자동으로 모든 테이블에 적용되므로, 30개 이상의 테이블도 효율적으로 관리 가능
🔹 3단계: 자주 실행하는 쿼리 최적화
📌 어떤 쿼리가 가장 느린지 확인하고 최적화
SQL Server에서 sys.dm_exec_query_stats를 사용하면 실행 속도가 느린 쿼리를 찾을 수 있음
1️⃣ 가장 오래 걸리는 쿼리 찾기
SELECT TOP 10
total_worker_time/execution_count AS Avg_CPU_Time,
total_elapsed_time/execution_count AS Avg_Run_Time,
execution_count,
text AS QueryText
FROM sys.dm_exec_query_stats
CROSS APPLY sys.dm_exec_sql_text(sql_handle)
ORDER BY Avg_Run_Time DESC;
👉 Avg_Run_Time 값이 높은 쿼리를 최적화해야 함
2️⃣ 쿼리 실행 계획 확인 및 인덱스 추가 실행 계획을 분석하여 INDEX SCAN이 발생하는 경우 INDEX SEEK로 변경해야 함
SET SHOWPLAN_XML ON;
EXEC sp_executesql N'SELECT * FROM sales WHERE order_date > ''2023-01-01''';
SET SHOWPLAN_XML OFF;
INDEX SCAN → 해당 칼럼에 적절한 인덱스 추가
CREATE INDEX idx_sales_order_date ON sales(order_date);
✅ 효과
가장 느린 쿼리를 최적화하여 전체적인 응답 속도 개선
불필요한 INDEX SCAN을 제거하여 성능 향상
🔹 4단계: 유지보수 자동화 (주기적 최적화 작업)
📌 30개 이상의 테이블을 효율적으로 유지관리하려면 자동화 작업을 추가해야 함
✅ 1️⃣ 매주 자동 인덱스 재구성
SQL Server Agent에서 자동화 스케줄링 설정
CREATE PROCEDURE dbo.RebuildIndexes
AS
BEGIN
EXEC sp_MSForEachTable 'ALTER INDEX ALL ON ? REBUILD';
END;
GO
EXEC dbo.RebuildIndexes;
👉 매주 실행되도록 예약하면, 자동으로 인덱스를 최적화
✅ 2️⃣ 매일 자동 통계 업데이트
EXEC sp_MSForEachTable 'UPDATE STATISTICS ?';
👉 최신 데이터에 맞게 실행 계획을 업데이트하여 성능 유지
✅ 3️⃣ 매일 자동 백업 실행
BACKUP DATABASE mydb TO DISK = 'C:\Backup\mydb_' + CONVERT(VARCHAR, GETDATE(), 112) + '.bak' WITH FORMAT, INIT;
👉 데이터 손실 방지를 위해 자동 백업 설정
💡 최적화 프로세스 요약
단계 | 작업 내용 | SQL 코드 |
1단계 | 오래된 데이터 아카이빙 | SELECT * INTO archive_table FROM sales WHERE order_date < '2014-01-01'; |
2단계 | 전체 인덱스 재구성 | EXEC sp_MSForEachTable 'ALTER INDEX ALL ON ? REBUILD'; |
3단계 | 느린 쿼리 최적화 | SELECT TOP 10 total_elapsed_time/execution_count AS Avg_Run_Time, text FROM sys.dm_exec_query_stats CROSS APPLY sys.dm_exec_sql_text(sql_handle); |
4단계 | 유지보수 자동화 | EXEC sp_MSForEachTable 'UPDATE STATISTICS ?'; |
5단계 | 자동 백업 설정 | BACKUP DATABASE mydb TO DISK = 'C:\Backup\mydb_' + CONVERT(VARCHAR, GETDATE(), 112) + '.bak'; |
🔹 결론
✅ 30개 이상의 테이블을 효율적으로 최적화하려면
데이터 정리: 오래된 데이터를 별도 테이블로 이동 (아카이빙)
인덱스 최적화: 모든 테이블의 인덱스를 자동으로 재구성
쿼리 최적화: 느린 쿼리를 찾아 실행 계획 분석 및 인덱스 추가
유지보수 자동화: 인덱스 최적화, 통계 업데이트, 자동 백업을 예약 실행
✅ 이 방법을 적용하면
운영 속도 향상
DB 부하 감소
관리 비용 절감