Каков самый быстрый способ загрузки XML-файла в MySQL с помощью C#?
вопрос
каков самый быстрый способ сбросить большой (>1GB) XML-файл в базу данных MySQL?
данные
данные, о которых идет речь, - это дамп данных Stackoverflow Creative Commons.
цель
это будет использоваться в автономном StackOverflow viewer я строю, так как я ищу, чтобы сделать некоторые исследования/кодирование в местах, где у меня не будет доступа к интернету.
Я хотел бы выпустить это членства StackOverflow для собственного использования, когда проект будет завершен.
Первоначально я читал из XML / записи в БД по одной записи за раз. Это заняло около 10 часов, чтобы запустить на моей машине. Код hacktastic, который я использую сейчас, бросает 500 записей в массив, а затем создает запрос вставки для загрузки всех 500 сразу (например. "INSERT INTO posts VALUES (...), (...), (...) ... ;
"). Хотя это быстрее, это все еще занимает часы, чтобы запустить. Очевидно, что это не лучший способ сделать это, поэтому я надеюсь большие мозги на этом сайте будут знать лучший способ.
ограничения
- я создаю приложение, используя C# в качестве настольного приложения (т. е. WinForms).
- я использую MySQL 5.1 в качестве моей базы данных. Это означает, что такие функции, как"
LOAD XML INFILE filename.xml
" не используются в этом проекте, так как эта функция доступна только в MySQL 5.4 и выше. Это ограничение во многом связано с моей надеждой, что проект будет полезен другим людям, кроме меня, и я бы скорее не заставляйте людей использовать бета-версии MySQL. - я хотел бы, чтобы загрузка данных была встроена в мое приложение (т. е. нет инструкций "загрузить дамп в MySQL с помощью" foo " перед запуском этого приложения.").
- я использую MySQL Connector / Net, поэтому что-нибудь в
MySql.Data
пространство имен является приемлемым.
Спасибо за любые указатели вы можете предоставить!
идеи до сих пор
сохраненные процедура, которая загружает весь XML-файл в столбец, а затем анализирует его с помощью XPath
- это не сработало, так как размер файла зависит от ограничений переменной max_allowed_packet, которая по умолчанию установлена в 1 МБ. Это намного меньше размера файлов дампа данных.
8 ответов
есть 2 части к этому:
- чтение xml-файла
- запись в базу данных
для чтения xml-файла эта ссылка http://csharptutorial.blogspot.com/2006/10/reading-xml-fast.html, показывает, что 1 МБ можно прочитать за 2,4 секунды с помощью stream reader, это будет 2400 секунд или 40 минут (если моя математика работает так поздно) для файла 1 ГБ.
из того, что я прочитал, самый быстрый способ получить данные в MySQL для использования данных загрузки.
http://dev.mysql.com/doc/refman/5.1/en/load-data.html
поэтому, если вы можете прочитать xml-данные, запишите их в файлы, которые могут использоваться данными загрузки, а затем запустите LOAD DATA. Общее время может быть меньше часов, что вы experiancing.
хорошо, я буду идиотом здесь и отвечу на ваш вопрос вопросом.
зачем помещать его в базу данных?
Что делать, если ... просто что-ли... вы записали xml в файлы на локальном диске и, при необходимости, записываете некоторую информацию индексирования в базу данных. Это должно выполняться значительно быстрее, чем пытаться загрузить базу данных, и будет намного более портативным. Все, что вам нужно, - это способ поиска и способ индексирования реляционные ссылки. Должно быть много помощи в поиске, и реляционный аспект должен быть достаточно легким для создания? Вы даже можете подумать о переписывании информации, чтобы каждый файл содержал одну запись со всеми ответами и комментариями прямо там.
в любом случае, просто мои два цента (и это не стоит ни копейки).
У меня есть несколько мыслей, чтобы помочь ускорить этот процесс...
размер запроса может потребоваться настроить, часто есть момент, когда большой оператор стоит больше времени разбора и поэтому становится медленнее. 500 может быть оптимальным, но, возможно, это не так, и вы можете настроить это немного (это может быть больше, это может быть меньше).
перейти многопоточный. Предполагая, что ваша система еще не выровнена по обработке, вы можете получить некоторые выгоды разбив данные на куски и обработав их потоками. Опять же, это эксперимент, чтобы найти оптимальное количество потоков, но многие люди используют многоядерные машины и имеют циклы процессора.
на передней панели базы данных убедитесь, что таблица настолько голая, насколько это возможно. Отключите все индексы и загрузите данные перед индексированием.
скалы SqlBulkCopy. Я использовал его, чтобы превратить 30-минутную функцию в 4 секунды. Однако это применимо только к MS SQL Server.
могу ли я предложить вам взглянуть на ограничения на вашей таблице, которую вы создали? Если вы отбросите все ключи в базе данных, ограничения и т. д., база данных будет делать меньше работы над вашими вставками и меньше рекурсивной работы.
во-вторых, настройте таблицы с большими начальными размерами, чтобы предотвратить изменение размера, если вы вставляете в пустое база данных.
наконец, посмотрите, есть ли API стиля массового копирования для MySQL. SQL Server в основном форматирует данные, как это будет идти на диск, и SQL server связывает поток до диска, и вы качаете данные. Затем он выполняет одну проверку согласованности для всех данных вместо одной вставки, что значительно повышает производительность. Удачи ;)
вам нужен MySQL? SQL Server упрощает жизнь при использовании Visual Studio и низкой базе данных производительность/размер.
тут этой помочь? Это хранимая процедура, которая загружает весь XML-файл в столбец, а затем анализирует его с помощью XPath и создает таблицу / вставляет данные оттуда. Кажется сумасшедшим, но это может сработать.
Не ответ, который вы хотите, но api mysql c имеет mysql_stmt_send_long_data
Я заметил в одном из ваших комментариев выше, что вы рассматриваете MSSQL, поэтому я подумал, что опубликую это. SQL Server имеет утилиту SQMLXMLBulkLoad, которая предназначена для импорта больших объемов XML-данных в базу данных SQL Server. Вот документация для версии SQL Sever 2008:
http://msdn.microsoft.com/en-us/library/ms171993.aspx
более ранние версии SQL Server также имеют эту утилиту
на PostgreSQL, абсолютный самый быстрый способ получить объемные данные - это удалить все индексы и триггеры, использовать эквивалент MySQL ЗАГРУЗИТЬ ДАННЫЕ а затем воссоздайте свои индексы/триггеры. Я использую этот метод, чтобы вытащить 5 ГБ данных форума в базу данных PostgreSQL примерно за 10 минут.
конечно, это может не относиться к MySQL, но это стоит попробовать. Кроме того,это так Вопрос ответ предполагает, что это на самом деле жизнеспособная стратегия для MySQL.
быстрый google нашел несколько советов по повышение производительности данных загрузки MySQL.