Самый быстрый импорт CSV в таблицу базы данных - PullRequest
2 голосов
/ 11 октября 2010

Я реализовал функцию импорта, которая берет данные из CSV-файла в приложении Asp.Net.Размер файла может варьироваться от нескольких килобайт до максимум 10 МБ.

Однако, когда происходит импорт и если размер файла> 50000, это занимает около 20 МИНУТ.Что слишком много времени.Мне нужно выполнить импорт около 300000 записей в течение 2-3 минут.

Я знаю, что импорт в базу данных также зависит от физической памяти сервера БД. Я массово создаю сценарии вставки и выполняю их.Я также знаю, что использование SqlBulkCopy также было бы другим вариантом, но в моем случае это просто не вставка продуктов, а также обновление и удаление, это поле с именем «FUNCTION CODE», которое решает, вставлять, обновлять или удалять.

Буду очень признателен за любые предложения относительно того, как это сделать.

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

Спасибо и С уважением, Фрэнсис П.

Ответы [ 5 ]

4 голосов
/ 11 октября 2010

SqlBulkCopy определенно будет самым быстрым. Я хотел бы подойти к этому, вставив данные во временную таблицу в базе данных. Когда данные находятся во временной таблице, вы можете использовать SQL для слияния / вставки / удаления соответственно.

1 голос
/ 11 октября 2010

Полагаю, вы используете SQL Server ...

Если вы используете 2005/2008, рассмотрите возможность использования SSIS для обработки файла. Technet

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

0 голосов
/ 11 октября 2010

Я предлагаю использовать функцию XML в SQL Server 2005/2008, которая позволит вам выполнять массовые вставки и массовые обновления. Я бы выбрал следующий подход:

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

У этого подхода есть множество преимуществ:

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

С точки зрения хранимого процесса вам понадобится что-то вроде следующего:

CREATE PROCEDURE MyBulkUpdater
(
   @p_XmlData VARCHAR(MAX)
)

AS
DECLARE @hDoc INT
EXEC sp_xml_preparedocument @hDoc OUTPUT, @p_XmlData

-- Temporary table, should contain the same schema as the table you want to update
CREATE TABLE #MyTempTable
(
   -- ...
)

INSERT INTO #MyTempTable
(
        [Field1],
        [Field2]
)
SELECT
        XMLData.Field1,
        XMLData.Field2
FROM OPENXML (@hdoc, 'ROOT/MyRealTable', 1)
WITH
(
        [Field1] int,
        [Field2] varchar(50),
        [__ORDERBY] int
) AS XMLData

EXEC sp_xml_removedocument @hDoc

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

INSERT INTO MyRealTable (Field1, Field2)
SELECT Field1, Field2
FROM #MyTempTable
WHERE ...

UPDATE MyRealTable
SET rt.Field2 = tt.Field2
FROM MyRealTable rt
JOIN MyTempTable tt ON tt.Field1 = MyRealTable.Field1
WHERE ...

Для примера XML, который вам нужно передать, вы можете сделать:

SELECT TOP 1 *, 0 AS __ORDERBY FROM MyRealTable AS MyRealTable FOR XML AUTO, ROOT('ROOT') 

Для получения дополнительной информации см. OPENXML , sp_xml_preparedocument и sp_xml_removedocument .

0 голосов
/ 11 октября 2010

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

Открытые X-соединения с базой данных (где вам нужно настроить X, но только начать с 5) и любой из них: раскрутить 5 потоков, каждый из которых выполняет частьта же самая работа, которую вы делали.или: используйте асинхронные вызовы и при поступлении обратного вызова снимите в следующем запросе.

0 голосов
/ 11 октября 2010

Если это повторяющийся процесс, и файл загружается через asp.net, плюс вы принимаете решение по поводу данных, чтобы принять решение о вставке / обновлении или удалении, тогда попробуйте http://www.codeproject.com/KB/database/CsvReader.aspx именно этот быстрый CSV читатель. Это довольно быстро и экономно с памятью

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