How to reduce size of SQL Server table that grew from a datatype change

回眸只為那壹抹淺笑 提交于 2019-11-28 06:25:03

Well it's clear you're not getting any space back ! :-)

When you changed your text fields to CHAR(60), they are all filled up to capacity with spaces. So ALL your fields are now really 60 characters long.

Changing that back to VARCHAR(60) won't help - the fields are still all 60 chars long....

What you really need to do is run a TRIM function over all your fields to reduce them back to their trimmed length, and then do a database shrinking.

After you've done that, you need to REBUILD your clustered index in order to reclaim some of that wasted space. The clustered index is really where your data lives - you can rebuild it like this:

ALTER INDEX IndexName ON YourTable REBUILD 

By default, your primary key is your clustered index (unless you've specified otherwise).

Marc

You have not cleaned or compacted any data, even with a "shrink database".

DBCC CLEANTABLE

Reclaims space from dropped variable-length columns in tables or indexed views.

However, a simple index rebuild if there is a clustered index should also do it

ALTER INDEX ALL ON dbo.Mytable REBUILD

A worked example from Tony Rogerson

I know I'm not answering your question as you are asking, but have you considered archiving some of the data to a history table, and work with fewer rows?

Most of the times you might think at first glance that you need all that data all the time but when actually sitting down and examining it, there are cases where that's not true. Or at least I've experienced that situation before.

Robin Day

I had a similar problem here SQL Server, Converting NTEXT to NVARCHAR(MAX) that was related to changing ntext to nvarchar(max).

I had to do an UPDATE MyTable SET MyValue = MyValue in order to get it to resize everything nicely.

This obviously takes quite a long time with a lot of records. There were a number of suggestions as how better to do it. They key one was a temporary flag indicated if it had been done or not and then updating a few thousand at a time in a loop until it was all done. This meant I had "some" control over how much it was doing.

On another note though, if you really want to shrink the database as much as possible, it can help if you turn the recovery model down to simple, shrink the transaction logs, reorganise all the data in the pages, then set it back to full recovery model. Be careful though, shrinking of databases is generally not advisable, and if you reduce the recovery model of a live database you are asking for something to go wrong.

Alternatively, you could do a full table rebuild to ensure there's no extra data hanging around anywhere:

CREATE TABLE tmp_table(<column definitions>);
GO
INSERT INTO tmp_table(<columns>) SELECT <columns> FROM <table>;
GO
DROP TABLE <table>;
GO
EXEC sp_rename N'tmp_table', N'<table>';
GO

Of course, things get more complicated with identity, indexes, etc etc...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!