Как скопировать огромные данные таблицы в другую таблицу в SQL Server - PullRequest
27 голосов
/ 14 марта 2011

У меня есть таблица с 3,4 млн строк. Я хочу скопировать все эти данные в другую таблицу.

Я выполняю эту задачу, используя следующий запрос:

select * 
into new_items 
from productDB.dbo.items

Мне нужно знать, как лучше всего выполнить эту задачу.

Ответы [ 8 ]

70 голосов
/ 09 сентября 2011

У меня была такая же проблема, за исключением того, что у меня есть таблица с 2 миллиардами строк, поэтому файл журнала будет расти до бесконечности, если я это сделаю, даже если для модели восстановления задано Bulk-Logging:

insert into newtable select * from oldtable

Так что я оперирую блоками данных.Таким образом, если передача прервана, вы просто перезапустите ее.Кроме того, вам не нужен файл журнала размером с таблицу.Похоже, вы также получаете меньше ввода-вывода tempdb, но не знаете почему.

set identity_insert newtable on
DECLARE @StartID bigint, @LastID bigint, @EndID bigint
select @StartID = isNull(max(id),0) + 1
from newtable

select @LastID = max(ID)
from oldtable

while @StartID < @LastID
begin
    set @EndID = @StartID + 1000000

    insert into newtable (FIELDS,GO,HERE)
    select FIELDS,GO,HERE from oldtable (NOLOCK)
    where id BETWEEN @StartID AND @EndId

    set @StartID = @EndID + 1
end
set identity_insert newtable off
go

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

14 голосов
/ 14 марта 2011

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

Есливаши строки очень большие, вы можете использовать функции массовой вставки в SQL Server.Я думаю, что вы можете вызвать их из C #.

Или вы можете сначала загрузить эти данные в текстовый файл, а затем скопировать их (bcp).Это дает дополнительное преимущество: вы можете игнорировать ключи, индексы и т. Д.

Также попробуйте утилиту импорта / экспорта, которая поставляется вместе с SQL Management Studio;не уверен, будет ли это так же быстро, как обычная массовая копия, но он должен позволить вам пропустить промежуточный этап записи в виде плоского файла и просто скопировать непосредственно из таблицы в таблицу, что может быть немного быстрее, чемваше SELECT INTO заявление.

10 голосов
/ 22 декабря 2015

Я работал с нашим администратором базы данных, чтобы скопировать таблицу аудита с 240M строками в другую базу данных.

С помощью простого выбора / вставки создан огромный файл tempdb.

Использование мастера импорта / экспорта работало, но скопировало 8M строк за 10 минут

Создание пользовательского пакета служб SSIS и настройка параметров скопированных 30M строк в 10 минут

Пакет служб SSIS оказался самым быстрым и эффективным для наших целей

Earl

5 голосов
/ 17 сентября 2015

Вот еще один способ переноса больших таблиц.Я только что перевел 105 миллионов строк между двумя серверами, используя это.Довольно быстро тоже.

  1. Щелкните правой кнопкой мыши базу данных и выберите Задачи / Экспорт данных .
  2. Мастер проведет вас по шагам, но вы выберете клиент SQL Server в качестве источника данных и цели, и вы сможете выбрать базу данных и таблицы, которые вы хотите перенести.

Для получения дополнительной информации см. https://www.mssqltips.com/sqlservertutorial/202/simple-way-to-export-data-from-sql-server/

3 голосов
/ 31 октября 2015

Если это однократный импорт, утилита импорта / экспорта в SSMS, вероятно, будет работать проще и быстрее.SSIS также, кажется, работает лучше для импорта больших наборов данных, чем прямая INSERT.

BULK INSERT или BCP также можно использовать для импорта больших наборов записей.

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

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

Вот несколько вариантов, которые можно попробовать.

-Эрик Исаакс

1 голос
/ 08 августа 2018

Простая вставка / выбор sp работает отлично, пока количество строк не превысит 1 мил.Я наблюдал, как файл tempdb взрывается, пытаясь вставить / выбрать 20 мил + строк.Самое простое решение - это SSIS, установив в качестве размера буфера пакетной строки значение 5000, а в качестве размера буфера - 1000.

0 голосов
/ 02 мая 2019

Если вы сосредоточены на архивировании (DW) и имеете дело с VLDB со 100+ многораздельными таблицами, и вы хотите изолировать большую часть этих ресурсоемких работ на непроизводственном сервере (OLTP), вот предложение (OLTP -> DW) 1) Используйте функцию резервного копирования / восстановления, чтобы перенести данные на сервер архивации (так что теперь в Archive или DW у вас будет база данных Stage and Target) 2) База данных этапов: используйте переключатель разделов для перемещения данных в соответствующую таблицу этапов
3) Используйте SSIS для передачи данных из поэтапной базы данных в целевую базу данных для каждой поэтапной таблицы с обеих сторон. 4) Целевая база данных: используйте переключатель разделов на целевой базе данных, чтобы переместить данные из рабочей области в базовую таблицу. Надеюсь, это поможет.

0 голосов
/ 14 марта 2011

выберите * в new_items из productDB.dbo.items

Это довольно много. Это самый эффективный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...