Blog Post

SQL database Incremental Shrink TSQL

,

When we shrink a SQL database through GUI we usually find the database never releases all the free space, It is always a good practice particularly in Production OLTP systems to shrink the database in small chunks so the data databse pages can be re-arranged and can free all unused space. The below TSQL will allow  shrink a database file in increments until it reaches a target free space limit.

/*

This script is used to shrink a database file in

increments until it reaches a target free space limit.

Run this script in the database with the file to be shrunk.

1. Set @DBFileName to the name of database file to shrink.

2. Set @TargetFreeMB to the desired file free space in MB after shrink.

3. Set @ShrinkIncrementMB to the increment to shrink file by in MB

4. Run the script

*/

set nocount on

declare @DBFileName sysname

declare @TargetFreeMB int

declare @ShrinkIncrementMBint

-- Set Name of Database file to shrink

set @DBFileName = ''

-- Set Desired file free space in MB after shrink

set @TargetFreeMB = 0

-- Set Increment to shrink file by in MB

set @ShrinkIncrementMB= 100

-- Show Size, Space Used, Unused Space, and Name of all database files

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 float

declare @UsedMB float

-- Get current file size in MB

select @SizeMB = size/128. from sysfiles where name = @DBFileName

-- Get current space used in MB

select @UsedMB = fileproperty( @DBFileName,'SpaceUsed')/128.0

-- Loop until file at desired size

while  @SizeMB > @UsedMB+@TargetFreeMB+@ShrinkIncrementMB

begin

 set @sql = 'dbcc shrinkfile ( '+@DBFileName+', ' + convert(varchar(20),@SizeMB-@ShrinkIncrementMB)+' ) WITH NO_INFOMSGS'

 print 'Start ' + @sql + ' at ' + convert(varchar(30),getdate(),121)

 exec ( @sql )

 print 'Done ' + @sql + ' at '+convert(varchar(30),getdate(),121)

 -- Get current file size in MB

 select @SizeMB = size/128. from sysfiles where name = @DBFileName

 -- Get current space used in MB

 select @UsedMB = fileproperty( @DBFileName,'SpaceUsed')/128.0

 print 'SizeMB=' + convert(varchar(20),@SizeMB) + ' UsedMB=' + convert(varchar(20),@UsedMB)

end

select [EndFileSize] = @SizeMB, [EndUsedSpace] = @UsedMB, [DBFileName] = @DBFileName

Read 199 times
(4 in last 30 days)

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating