Получение строк, вставленных с помощью SqlBulkCopy - PullRequest
0 голосов
/ 18 января 2011

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

Служба берет ваш пакет из 10 000 ссылок (импортированных из карты сайта, построителей обратных ссылок и т. Д.) И разбивает их на RSS-каналы X для каждого канала для агрегации. Проблема в том, что у меня уже есть таблица 32 миллиона строк . Если я делаю вставки linq to sql, то в зависимости от посещаемости сайта от 5 до 10 минут, чтобы загрузить 10000 ссылок.

Структура очень проста.

Feeds : идентификатор bigint (PK), заголовок varchar (1000), описание varchar (1000), опубликованный datetime, агрегированный datetime null, ShortCode varchar (8) [устарел, больше не вставляется, но используется для устаревших данных]

Элементы : Идентификатор bigint (PK), FeedId bigint (FK), Title varchar (1000), Description varchar (1000), Дата публикации-время, ShortCode varchar (8) [устарел, больше не вставляется, но используется для устаревших данных], ShortId bigint null [обновляется после вставки в равный Id (используется при разбиении)]

FutureItems : идентификатор bigint (PK), FeedId bigint (FK), заголовок varchar (1000), описание varchar (1000), дата публикации и время, ShortCode varchar (8) [устарел, больше не вставляется, но используется для устаревших данных], ShortId bigint null [обновляется после вставки в равный Id (используется при разбиении)]

OldItems : Идентификатор bigint (PK), FeedId bigint (FK), Название varchar (1000), Описание varchar (1000), Дата и время публикации, ShortCode varchar (8) [устарел, больше не вставляется, но используется для устаревших данных], ShortId bigint null [обновляется после вставки в равный Id (используется при разбиении)]

Таким образом, если у вас размер фида 20, вы получаете 500 вставок в таблицу Feeds, затем 10000 вставок в таблицу Items, затем запускается обновление, чтобы установить ShortId равным Id. Раз в ночь выполняется задание, которое разделяет данные на две другие таблицы и перемещает будущие элементы в таблицу «Элементы».

Я читал, что SqlBulkCopy может обрабатывать 20 миллионов строк за несколько минут, но не могу найти хороших примеров того, как сделать это в нескольких таблицах с ограничением FK.

Наш сервер SQL является "монстром" специально для этого приложения. Это SQL 2008 R2 Web, Windows 2008 R2 Enterprise, оперативная память 12 ГБ, двухъядерные двухъядерные Xeons @ 2,8 ГГц.

Наш веб-сервер является клоном без службы базы данных.

Процессор работает примерно на 85% при вставке ссылок, а база данных заполняет ОЗУ.

Если SqlBulkCopy не годится, любые предложения приветствуются, у нас есть платящие клиенты, которые злятся, а я не администратор баз данных, а просто старый программист.

Ответы [ 2 ]

1 голос
/ 19 января 2011

SqlBulkCopy действительно быстрее, чем обычные вставки. Но это быстрее, поскольку в нем можно преобразовать задание, которое выполняет 1000 вставок в секунду, в одно, которое выполняет 10000 / с. Если вы можете сделать только 10 000 ссылок за 10 минут, у вас должны быть другие проблемы, которые вряд ли решит массовая копия.

Сначала необходимо выяснить , почему требуется невероятно много времени, чтобы вставить 10000 ссылок. Только после того, как вы поймете, что вы можете позвонить, чтобы определить, является ли переход к SqlBulkCopy решением. Я понимаю, что вы не администратор баз данных, но я собираюсь направить вам технический документ dbaish для устранения неполадок производительности SQL Server: Ожидания и очереди . Это решение не для рецепта печенья, а на самом деле методология, которая научит вас определять узкие места производительности в SQL Server.

И чтобы ответить на ваш вопрос: как использовать SqlBulkCopy при наличии ограничений? Более общий вопрос: как выполнять массовые операции вставки при наличии ограничений? Для серьезных томов фактически отключаются ограничения, выполняются массовые загрузки, а затем включаются ограничения. Для более рационализированных онлайн-операций с минимальным временем простоя (база данных в основном «недоступна» на период, когда ограничения отключены), используется другая стратегия, а именно, она предварительно загружает данные в промежуточные таблицы, проверяет их и затем переключает их с операция переключения разделов, см. Эффективная передача данных с помощью переключения разделов .

0 голосов
/ 19 января 2011

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

...