Какой самый быстрый способ вставить миллионы строк в таблицу SQL в этом случае?

#c# #sql-server #sqlbulkcopy

#c# #sql-сервер #sqlbulkcopy

Вопрос:

Сценарий случая следующий. С помощью C # я вынужден вызывать хранимую процедуру на внешнем сервере, которая возвращает 50 миллионов записей при каждом ее вызове. Каждая запись состоит из нескольких полей, разделенных запятыми, которые я должен разделить и вставить в таблицу базы данных на другом сервере. Поскольку записи должны быть обработаны перед вставкой, я думаю, что использование SqlBulkCopy следует исключить, поскольку оно записывает данные в таблицу прибытия такими, какие они есть, а не разделенными. Сохранение всех записей в массиве является чрезмерно дорогостоящим, поскольку оперативной памяти компьютера, на котором .exe будет выполняться, недостаточно для этой цели. Есть идеи?

Комментарии:

1. Я вызываю хранимую процедуру на внешнем сервере, которая возвращает 50 миллионов записей при каждом ее вызове. Я вижу здесь проблему.

2. Возможно ли внести изменения на внешнем сервере?

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

4. Вы забыли, что эти 50 миллионов строк также содержат данные с разделителями, а не правильный набор данных, @Steve 😉 Я чувствую здесь проблемы XY.

5. Посмотрите, можете ли вы использовать SqlDataReader для потоковой передачи результатов и обработки их по одному за раз.

Ответ №1:

Класс SqlBulkCopy может передавать поток DataReader

Это означает, что вы можете создать пользовательский DataReader, который будет инкапсулировать DataReader, из которого поступают данные.

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

Используя EnablesStreaming = true , это гарантирует, что в памяти находится только небольшой объем данных.

Вы предлагаете мне реализовать интерфейс IDataReader?

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

Вот как на самом деле работают некоторые из моих библиотек о массовой вставке, такие как:

Под капотом мы используем пользовательский IDataReader для доступа к объектам и их обработки.

Комментарии:

1. Вы предлагаете мне реализовать интерфейс IDataReader?