2009-09-22 5 views
21

У меня есть таблица склада с 16 т данных в нем. У меня есть несколько столбцов Integer. Мы должны отнести их в BIGINT для каждого запроса, который мы пишем, потому что SUM слишком велик, чтобы вписаться в INT.Изменение INT на BigInt

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

Поскольку данные уже загружены, я решил использовать Management Studio и изменить тип данных. Но я сначала получить предупреждение:

Saving Definition Changes to tables with large amounts of data could take a considerable amount of time. While changes are being saved, table data will not be accessible.

Тогда я получаю сообщение об ошибке:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

Как обойти это?

+45

16 тонн данных - это очень много! – RedFilter

+0

Рассматривали ли вы временную таблицу, новую структуру, вставляете и заменяете? –

+2

@astander - это, по сути, то, что изменение схемы в SSMS делает под капотом. – tvanfosson

ответ

43

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

ALTER TABLE monster ALTER COLUMN MyIntCol1 bigint

Изменения в Studio Management Studio редко являются наиболее эффективными и, как правило, благоприятствуют временным таблицам для любого изменения существующего столбца.

+1

Интересно, не знал, что Studio Management была неэффективной в этом отношении. – RedFilter

24

Не уверен, если это поможет, но попробовать это:

1 - create a new bigint column in the table 
2 - update that new column with the values from the int column 
3 - delete the int column 
4 - rename the bigint column 
+3

+1, то же самое, что я пытался набрать! –

+0

То же самое я набрал то же самое. (+1) Я собирался добавить, что это работает и при репликации. –

+1

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

2

расширить на OrbMan's ответ:

  • добавить новые столбцы в нижней части списка столбцов (это ускорит его)
  • вы можете сделать ваши обновления партиями по 10 000 строк или около того, если необходимо
  • убедитесь, что вы находитесь в однопользовательском режиме или в приложении, если «ВЫКЛ», так что никто больше не изменяет данные в этой таблице

Также, чтобы увидеть всю работу, которую студия управления делает при изменении таблицы, щелкните значок панели инструментов, который выглядит как прокрутка с дискеткой на нем. Это покажет фактические команды SQL, используемые для изменения вашей таблицы.

7

Я думаю, что основная ошибка, с которой вы, возможно, сталкиваетесь, заключается в том, что графический интерфейс - это тайм-аут. Когда вы применяете большие изменения, используя выбор «Изменить» из SSMS, он будет отключен. Если вы возьмете ту же команду, создав сценарий изменений в SSMS, а затем запустите его как прямой SQL-запрос, он будет работать до завершения.

2

Если исходные данные никогда не превышают предел INT, просто создайте VIEW, который поднимет этот столбец BIGINT и запросит об этом.

7

Этот метод работал очень хорошо для меня.

я выполнил:

use [Mytable] 
ALTER TABLE [dbo].[USER] ALTER COLUMN USER_ID bigint NOT NULL 

В результате этой ошибки, потому что было ограничение по ключу:

Msg 5074, Level 16, State 1, Line 2 
The object 'PK_USER_USER_ID' is dependent on column 'USER_ID'. 
Msg 4922, Level 16, State 9, Line 2 
ALTER TABLE ALTER COLUMN USER_ID failed because one or more objects access this column. 

Не быть удержаны в управления SQL Server Studio я прав щелкнул на ограничение PK_USER_USER_ID, затем выберите «Сценарий в качестве >> Отбросьте и создайте в >> Окно редактора новых запросов»:

enter image description here

Это породило этот сценарий:

USE [Database] 
GO 
/****** Object: Index [PK_USER_USER_ID] Script Date: 18/03/2014 13:05:38 ******/ 
ALTER TABLE [dbo].[USER] DROP CONSTRAINT [PK_USER_USER_ID] 
GO 

/****** Object: Index [PK_USER_USER_ID] Script Date: 18/03/2014 13:05:38 ******/ 
ALTER TABLE [dbo].[USER] ADD CONSTRAINT [PK_USER_USER_ID] PRIMARY KEY CLUSTERED 
(
[USER_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,  ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

Я тогда выполнялась первая половина этого сценария, чтобы уронить ограничение:

ALTER TABLE [dbo].[USER] DROP CONSTRAINT [PK_USER_USER_ID] 
GO 

Теперь, когда ограничение ушел , первоначальное изменение сработало красиво:

use [Mytable] 
ALTER TABLE [dbo].[USER] ALTER COLUMN USER_ID bigint NOT NULL 

Затем я выполнил вторую половину сценария, чтобы добавить ограничение назад в:

ALTER TABLE [dbo].[USER] ADD CONSTRAINT [PK_USER_USER_ID] PRIMARY KEY CLUSTERED 
(
[USER_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,  ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 
Смежные вопросы