이 질문은 여기에서 다양한 형태로 요청되지만 그 질문은 다음과 같이 요약됩니다.
데이터베이스 축소가 위험하다는 것을 알고 있습니다. 이 경우 너무 많은 데이터를 제거했으며 다시는 사용하지 않습니다.
- 데이터베이스를 축소하는 방법 어떤 파일을 축소합니까?
- 이 작업을 수행하는 동안 고려해야 할 사항은 무엇입니까?
- 나중에 무엇을해야합니까?
- 큰 데이터베이스 인 경우 어떻게합니까? 더 작은 단위로 축소 할 수 있습니까?
이 질문은 여기에서 다양한 형태로 요청되지만 그 질문은 다음과 같이 요약됩니다.
데이터베이스 축소가 위험하다는 것을 알고 있습니다. 이 경우 너무 많은 데이터를 제거했으며 다시는 사용하지 않습니다.
답변:
일부 초기주의 사항 :
우려와 위험에 대해 읽었으며 상당한 공간을 확보 했기 때문에 여전히 축소를 수행해야하는 경우이 답변의 나머지 부분이 도움이 될 것입니다. 그러나 위험을 고려하십시오.
두 가지 주요 접근 방식이 여기에 있습니다.
1.) 축소 예, 실제 축소를 수행하십시오.DBCC SHRINKFILE
대신 사용 을 고려하십시오 DBCC SHRINKDATABASE
. 이로 인해 성능이 약간 저하 될 수 있습니다. 많은 IO를 수행하는 대규모 작업입니다. 점진적으로 작아지는 대상 크기로 반복 축소하여 잠재적으로 벗어날 수 있습니다 .
위의 DBCC SHRINKFILE
링크 에서 "A.)"예입니다.이 예에서 데이터 파일이 7MB 대상 크기로 축소되었습니다. 이 형식은 가동 중지 시간 창에서 허용하는대로 반복적으로 축소하는 좋은 방법입니다. 나는 개발 테스트에서 성능이 어떻게 보이고 얼마나 낮은 / 높이가 증가하는지 그리고 생산의 예상 타이밍을 결정하기 위해 이것을 할 것입니다. 이것은 온라인 작업입니다. 시스템에서 축소 된 데이터베이스에 액세스하는 사용자와 함께 실행할 수 있지만 성능이 저하되어 거의 보장됩니다. 따라서 서버에서 수행중인 작업을 모니터링하고보고 중단 시간 창 또는 더 가벼운 활동 기간을 선택하십시오.
USE YourDatabase;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO
항상 기억하십시오 : -축소 할 때마다 인덱스를 조각화하고 장기간에 걸쳐 청크를 축소하려는 경우 인덱스를 다시 작성해야합니다. 한 창에서 모든 작업을 수행 할 수없는 경우 매번 그 비용이 발생합니다.
2) 새 데이터베이스 - 당신은 할 수 여기에 새 데이터베이스 및 마이그레이션 데이터를 생성합니다. 빈 데이터베이스와 모든 키, 인덱스, 개체, 프로세스, 함수 등을 스크립팅 한 다음 데이터를 마이그레이션해야합니다. 이를 위해 스크립트를 작성하거나 Red Gate의 SQL Data Compare와 같은 도구 또는 유사한 도구를 가진 다른 공급 업체를 사용할 수 있습니다. 이것은 사용자 측에서 더 많은 설정 작업, 더 많은 개발 및 테스트이며, 환경에 따라 다운 타임을 줄일 수도 있지만 고려해야 할 옵션이 있습니다.
데이터베이스를 축소 해야 할 때 이것이 내 환경이라면, 디스크 호그 인 것을 좋아하고 미래 / 예기치 않은 성장에 대비하기 위해 데이터 파일에 공평하고 많은 양의 공백을 남기고 싶습니다. 우리는 단지 공간의 대부분을 삭제 한 경우 나는 괜찮주는 공간 돌아올 것입니다,하지만 난 그 말을 "하지만 다시 성장하지 않습니다"아직도 떠나지 신뢰 없었어요 그래서 약간의 공백을. 아마 내가 갈 경로 ( 한숨)은 다운 타임 창이 더 작고 빈 DB를 만들고 데이터를 마이그레이션하는 복잡성을 원치 않는 경우 축소 방식입니다. 나는 그것을 점진적으로 시간의 무리를 축소 할 수 있도록 인덱스를 다시 다음과 (점진적으로 작은 파일 크기를 선택. 내가 dev에 원하는 크기로 내 테스트를 기반으로 필요하다고 생각하는 횟수 기준) .. 그리고 나서 ' d 내 데이터베이스를 축소했다고 말하지 마십시오 ;-)
DBCC SHRINKFILE
언급 한 명령으로 파일을 개별적으로 축소 할 수 있습니다 . 데이터베이스가 구성하는 파일 수는 서버에 따라 다릅니다. 단순 데이터베이스에는 하나의 데이터베이스 파일과 하나의 트랜잭션 로그 파일이 있습니다.어쨌든 SHRINK를 정기적으로 수행하지 않는 것이 좋습니다. 어쨌든 당신이 아마 알고있는 모든 경고와 면책 조항을 없애려고 노력합니다. 백업하고 가능하면 집에서하지 마십시오 :)
보너스 : 복제 환경에서 게시자 데이터베이스에서이 작업을 수행하면 구독자 데이터베이스가 축소되지 않습니다 (Express 버전이므로 크기 문제가있을 수 있음).
마지막으로, 재색 인 스크립트 :
USE YourDBName
DECLARE @TbName VARCHAR(255)
DECLARE @FullTbName VARCHAR(255)
DECLARE @IxName VARCHAR(255)
DECLARE myCursor CURSOR FOR
SELECT OBJECT_NAME(dmi.object_id) AS TableName,i.name AS IndexName
FROM sys.dm_db_index_physical_stats(14, NULL, NULL, NULL , 'LIMITED') dmi
JOIN sys.indexes i on dmi.object_id = i.object_id and dmi.index_id = i.index_id
WHERE avg_fragmentation_in_percent > 30
ORDER BY avg_fragmentation_in_percent
OPEN myCursor
FETCH NEXT FROM myCursor INTO @TbName, @ixName
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dba' AND TABLE_NAME = @TbName)
BEGIN
SET @FullTbName = 'dba.' + @TbName
IF (@ixName IS NULL)
BEGIN
PRINT 'Reindexing Table ' + @FullTbName
DBCC DBREINDEX(@FullTbName, '', 0)
END
ELSE
BEGIN
PRINT 'Reindexing Table ' + @FullTbName + ', Index ' + @IxName
DBCC DBREINDEX(@FullTbName, @IxName, 0)
END
END
FETCH NEXT FROM myCursor INTO @TbName, @ixName
END
CLOSE myCursor
DEALLOCATE myCursor
여기서 유일한 변수는 14이며 select를 실행하여 얻을 수 있으며 DB_ID('YourDBName')
스크립트는 dba. * 스키마의 테이블에만 관심이 있다고 가정합니다.
데이터베이스 축소에 대한 모든 경고를 들었으며 모두 사실입니다. 인덱스를 조각화하고 일반적으로 데이터베이스를 정리하여 프로덕션 시스템에서 수행해서는 안됩니다.
그러나 SSD 드라이브의 공간으로 인해 워크 스테이션에서 백업을 복원 할 때 일반적으로 주 단위로 수행합니다. 이 스크립트를 쓰지 않았지만 몇 년 전에 찾았습니다. 다른 데이터베이스 (250GB)에서 필자는 필요한 테이블을 전송 한 다음 인덱스 인덱스를 새로 생성하는 SSIS 패키지를 만들었습니다.
DECLARE @DBFileName SYSNAME
DECLARE @TargetFreeMB INT
DECLARE @ShrinkIncrementMB INT
SET @DBFileName = 'Set Name of Database file to shrink'
-- Set Desired file free space in MB after shrink
SET @TargetFreeMB = 500
-- Set Increment to shrink file by in MB
SET @ShrinkIncrementMB = 100
SELECT [FileSizeMB] = convert(NUMERIC(10, 2),
round(a.size / 128., 2)),
[UsedSpaceMB] = convert(NUMERIC(10, 2),
round(fileproperty(a.NAME, 'SpaceUsed') / 128., 2)),
[UnusedSpaceMB] = convert(NUMERIC(10, 2),
round((a.size - fileproperty(a.NAME, 'SpaceUsed')) / 128., 2)),
[DBFileName] = a.NAME
FROM sysfiles a
DECLARE @sql VARCHAR(8000)
DECLARE @SizeMB INT
DECLARE @UsedMB INT
SELECT @SizeMB = size / 128.
FROM sysfiles
WHERE NAME = @DBFileName
SELECT @UsedMB = fileproperty(@DBFileName, 'SpaceUsed') / 128.
SELECT [StartFileSize] = @SizeMB
,[StartUsedSpace] = @UsedMB
,[DBFileName] = @DBFileName
WHILE @SizeMB > @UsedMB + @TargetFreeMB + @ShrinkIncrementMB
BEGIN
SET @sql = 'dbcc shrinkfile ( ' + @DBFileName + ', ' + convert(VARCHAR(20), @SizeMB - @ShrinkIncrementMB) + ' ) '
PRINT 'Start ' + @sql
PRINT 'at ' + convert(VARCHAR(30), getdate(), 121)
EXEC (@sql)
PRINT 'Done ' + @sql
PRINT 'at ' + convert(VARCHAR(30), getdate(), 121)
SELECT @SizeMB = size / 128.
FROM sysfiles
WHERE NAME = @DBFileName
SELECT @UsedMB = fileproperty(@DBFileName, 'SpaceUsed') / 128.
SELECT [FileSize] = @SizeMB
,[UsedSpace] = @UsedMB
,[DBFileName] = @DBFileName
END
SELECT [EndFileSize] = @SizeMB
,[EndUsedSpace] = @UsedMB
,[DBFileName] = @DBFileName
SELECT [FileSizeMB] = convert(NUMERIC(10, 2), round(a.size / 128., 2))
,[UsedSpaceMB] = convert(NUMERIC(10, 2), round(fileproperty a.NAME, 'SpaceUsed') / 128., 2))
,[UnusedSpaceMB] = convert(NUMERIC(10, 2), round((a.size - fileproperty(a.NAME, 'SpaceUsed')) / 128., 2))
,[DBFileName] = a.NAME
FROM sysfiles a
아래 인용문은 Microsoft에서 직접 제공 한 것으로 (버전 2008-2016에 적용), 언제 / 언제, DBCC SHRINKFILE
명령 사용 방법에 대한 지침을 제공합니다 .
https://msdn.microsoft.com/en-us/library/ms189493.aspx
모범 사례
파일을 축소 할 때는 다음 정보를 고려하십시오.
- 축소 작업은 자르기 테이블 또는 테이블 삭제 작업과 같이 사용하지 않는 공간을 많이 만드는 작업 후에 가장 효과적입니다.
- 대부분의 데이터베이스는 일상적인 작업에 사용 가능한 여유 공간이 필요합니다. 데이터베이스를 반복적으로 축소하고 데이터베이스 크기가 다시 커지면 일반 작업에 줄어든 공간이 필요함을 나타냅니다. 이 경우 데이터베이스를 반복적으로 축소하는 것은 낭비되는 작업입니다.
- 축소 작업은 데이터베이스에서 인덱스의 조각화 상태를 유지하지 않으며 일반적으로 조각화를 어느 정도 증가시킵니다. 이것이 데이터베이스를 반복적으로 축소하지 않는 또 다른 이유입니다.
- 동일한 데이터베이스에서 여러 파일을 동시에 대신에 축소합니다. 시스템 테이블의 경합으로 인해 차단으로 인해 지연이 발생할 수 있습니다.