Как уменьшить размер таблицы SQL Server, которая выросла от изменения типа данных

Вот что я сделаю ...

  1. Создайте новую таблицу с уникальным столбцом email

    CREATE TABLE `emails` (
      id INT(3) PRIMARY KEY AUTO_INCREMENT,
      email VARCHAR(255) UNIQUE
    );
    
  2. Заполните ее текущими данными

    INSERT INTO `emails` (`email`)
    SELECT DISTINCT `email` FROM `some_mystery_table`
    ORDER BY `email`;
    
  3. Измените ваши существующие таблицы, чтобы они ссылались на emails(id) как внешний ключ. Это может быть немного сложнее, так как вам нужно (вероятно)

    1. Добавить новый столбец int email_id, где это необходимо
    2. Обновить данные с помощью id значение, соответствующее адресу электронной почты

      UPDATE some_mystery_table, emails
      INNER JOIN emails ON some_mystery_table.email = emails.email
      SET some_mystery_table.email_id = emails.id;
      
    3. Удалить столбец email

    4. Добавить внешний ключ, где email_id ссылается на emails(id) ]
  4. При отображении ваших данных и вам нужно заполненное нулями электронное письмо id, присоединитесь к таблице emails, например,

    SELECT a.whatever, e.email, LPAD(e.id, 3, '0') AS email_id
    FROM some_mystery_table a
    INNER JOIN emails e ON a.email_id = e.id;
    
  5. [ 1124]

    При добавлении новых записей электронной почты вы сначала добавляете их в emails, а затем используете сгенерированный id в любых других связанных таблицах.

  6. [1 125]
20
задан Christopher Rapcewicz 9 December 2013 в 12:09
поделиться

5 ответов

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

17
ответ дан 29 November 2019 в 23:37
поделиться

Вы не очищали и не сжимали никакие данные, даже с помощью «сжатой базы данных».

DBCC CLEANTABLE

Возвращает пространство из удаленных столбцов переменной длины в таблицах или индексированных представлениях.

Тем не менее, простое перестроение индекса , если существует кластерный индекс , также должно это сделать

ALTER INDEX ALL ON dbo.Mytable REBUILD

Рабочий пример от Тони Роджерсона

25
ответ дан 29 November 2019 в 23:37
поделиться

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...

0
ответ дан 29 November 2019 в 23:37
поделиться

Я знаю, что не отвечаю на ваш вопрос так, как вы спрашиваете, но рассматривали ли вы возможность архивирования некоторых данных в таблицу истории и работы с меньшим количеством строк?

В большинстве случаев на первый взгляд может показаться, что вам нужны все эти данные постоянно, но когда вы на самом деле садитесь и изучаете их, бывают случаи, когда это не так. Или, по крайней мере, я сталкивался с такой ситуацией раньше.

2
ответ дан 29 November 2019 в 23:37
поделиться

I здесь была похожая проблема SQL Server, преобразование NTEXT в NVARCHAR (MAX) , что было связано с изменением ntext на nvarchar (max).

Мне пришлось сделать ОБНОВЛЕНИЕ MyTable SET MyValue = MyValue , чтобы заставить его все хорошо изменить размер.

Очевидно, что это занимает довольно много времени с большим количеством записей. Было несколько предложений, как лучше это сделать. На первом ключе был временный флаг, обозначенный, если это было сделано, или нет, а затем обновлялось несколько тысяч за раз в цикле, пока все не было сделано. Это означало, что у меня был «некоторый» контроль над тем, сколько он делал.

С другой стороны, если вы действительно хотите максимально сократить базу данных, это может помочь, если вы превратите модель восстановления в простую, уменьшенную. журналы транзакций, реорганизуйте все данные на страницах, а затем верните их к модели полного восстановления. Однако будьте осторожны, сокращение баз данных, как правило, нежелательно, и если вы уменьшаете модель восстановления работающей базы данных, вы просите что-то сделать не так.

это может помочь, если вы превратите модель восстановления в простую, сократите журналы транзакций, реорганизуете все данные на страницах, а затем вернете ее к модели полного восстановления. Однако будьте осторожны, сокращение баз данных, как правило, нежелательно, и если вы уменьшаете модель восстановления работающей базы данных, вы просите что-то сделать не так.

это может помочь, если вы превратите модель восстановления в простую, сократите журналы транзакций, реорганизуете все данные на страницах, а затем вернете ее к модели полного восстановления. Однако будьте осторожны, сокращение баз данных, как правило, нежелательно, и если вы уменьшаете модель восстановления работающей базы данных, вы просите что-то сделать не так.

0
ответ дан 29 November 2019 в 23:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: