C # Импорт большого объема данных из CSV в базу данных - PullRequest
10 голосов
/ 15 апреля 2010

Какой самый эффективный способ загрузки больших объемов данных из CSV (3 миллиона + строк) в базу данных.

  • Данные должны быть отформатированы (например, столбец имени должен быть разбит на имя и фамилию и т. Д.)
  • Мне нужно сделать это максимально эффективно, т. Е. Ограничения по времени

Я предпочитаю читать, преобразовывать и загружать данные, используя приложение C # строка за строкой? Это идеал, если нет, каковы мои варианты? Стоит ли использовать многопоточность?

Ответы [ 7 ]

4 голосов
/ 15 апреля 2010

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

В прошлый раз, когда я сделал это, это было около дюжины строк C #. В одном потоке он работал на жестком диске так быстро, как мог читать данные с пластин. Я читаю по одной строке за раз из исходного файла.

Если вы не хотите писать сами, попробуйте библиотеки FileHelpers . Возможно, вы также захотите взглянуть на работу Себастьяна Лориона . Его CSV-ридер написан специально для решения проблем с производительностью.

3 голосов
/ 15 апреля 2010

Вы можете использовать csvreader для быстрого чтения CSV.

Предполагая, что вы используете SQL Server, вы используете csvreader CachedCsvReader для чтения данных в таблицу данных, которую вы можете использовать с SqlBulkCopy для загрузки в SQL Server.

2 голосов
/ 15 апреля 2010

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

Кроме того, я бы предложил пакетировать операторы вставки (включая много операторов вставки в одну строку) перед отправкой их в базу данных, если это не создает проблем при получении значений сгенерированного ключа, которые необходимо использовать для последующих внешних ключей (надеюсь вам не нужно извлекать какие-либо сгенерированные значения ключа). Помните, что SQL Server (если это то, что вы используете) может обрабатывать только 2200 параметров на пакет, поэтому ограничьте размер пакета, чтобы учесть это. И я бы рекомендовал использовать параметризованные операторы TSQL для выполнения вставок. Я подозреваю, что больше времени будет потрачено на вставку записей, чем на чтение их из файла.

1 голос
/ 15 апреля 2010

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

Если данные не могут быть импортированы с использованием BCP (что звучит так, как будто это невозможно, если требуется значительная обработка), то SSIS, вероятно, станет следующим быстрым вариантом. Это не самая лучшая платформа для разработки в мире, но она очень быстрая. Конечно, быстрее, чем любое приложение, которое вы могли бы написать самостоятельно в любое разумное время.

0 голосов
/ 15 апреля 2010

Если вы действительно хотите сделать это в C #, создать и заполнить DataTable, усечь целевую таблицу БД, а затем использовать System.Data.SqlClient.SqlBulkCopy.WriteToServer (DataTable dt).

0 голосов
/ 15 апреля 2010

прочитайте содержимое файла CSV построчно в DataTable в памяти. Вы можете манипулировать данными (т. Е. Разделять имя и фамилию) и т. Д. При заполнении таблицы данных.

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

См. http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.writetoserver.aspx для документации.

0 голосов
/ 15 апреля 2010

BCP довольно быстрый, поэтому я бы использовал его для загрузки данных. Для работы со строками я бы пошел с функцией CLR на SQL, как только данные будут там. Многопоточность не поможет в этом сценарии, кроме как для повышения сложности и снижения производительности.

...