使用C#将XML文件加载到MySQL的最快方法是什么?

将大型(> 1GB)XML文件转储到MySQL数据库的最快方法是什么?

数据

有问题的数据是StackOverflow Creative Commons Data Dump。

目的

这将在我正在构建的离线StackOverflow查看器中使用,因为我希望在我无法访问互联网的地方进行一些学习/编码。

我希望在项目完成后将其发布到StackOverflow成员的其余部分以供自己使用。

问题

最初,我一次读取XML /写入DB一条记录。 这需要大约10个小时才能在我的机器上运行。 我正在使用的hacktastic代码现在将500个记录抛出到一个数组中,然后创建一个插入查询以一次加载所有500个(例如“ INSERT INTO posts VALUES (...), (...), (...) ... ; “)。 虽然速度更快,但仍需要数小时才能运行。 显然,这不是最好的方法,所以我希望这个网站上的大脑会知道更好的方法。

约束

  • 我正在使用C#构建应用程序作为桌面应用程序(即WinForms)。
  • 我使用MySQL 5.1作为我的数据库。 这意味着诸如“ LOAD XML INFILE filename.xml ”之类的function在此项目中不可用,因为此function仅在MySQL 5.4及更高版本中可用。 这种约束很大程度上是因为我希望该项目对我以外的人有用,而且我宁愿不强迫人们使用Beta版本的MySQL。
  • 我希望将数据加载到我的应用程序中(即没有指令“在运行此应用程序之前使用’foo’将转储加载到MySQL中。”)。
  • 我正在使用MySQL Connector / Net,因此MySql.Data命名空间中的任何内容都是可以接受的。

感谢您提供的任何指示!


到目前为止的想法

将整个XML文件加载到列中的存储过程,然后使用XPath对其进行解析

  • 这不起作用,因为文件大小受max_allowed_pa​​cket变量的限制,默认情况下设置为1 MB。 这远远低于数据转储文件的大小。

这有两个部分:

  • 读取xml文件
  • 写入数据库

对于读取xml文件,此链接http://csharptutorial.blogspot.com/2006/10/reading-xml-fast.html显示,使用流读取器可以在2.4秒内读取1 MB,即2400秒或对于1 GB文件,40分钟(如果我的数学工作这么晚)。

从我所读到的,获取数据到MySQL的最快方法是使用LOAD DATA。

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

因此,如果您可以读取xml数据,请将其写入可由LOAD DATA使用的文件,然后运行LOAD DATA。 总时间可能少于您正在试验的小时数。

好的,我会在这里成为一个白痴,并回答你的问题。

为什么把它放在数据库中?

如果…只是假设…你将xml写入本地驱动器上的文件,如果需要,在数据库中写入一些索引信息。 这应该比尝试加载数据库快得多,并且可以更加轻松。 您需要的只是一种搜索方式和索引关系引用的方法。 搜索应该有很多帮助,关系方面应该很容易构建? 您甚至可以考虑重新编写信息,以便每个文件都包含一个包含所有答案和注释的post。

无论如何,只是我的两美分(这不值一角钱)。

我有一些想法可以帮助加快这个速度……

  1. 查询的大小可能需要调整,通常有一点,大语句在解析时间上花费更多,因此变得更慢。 500可能是最佳的,但也许它不是,你可以调整一点(它可能更多,它可能会更少)。

  2. 去multithreading。 假设您的系统在处理过程中尚未完全平坦,您可以通过将数据分解为块并让线程处理它们来获得一些收益。 同样,找到最佳线程数是一个实验性的事情,但是很多人正在使用多核机器并且有多余的CPU周期。

  3. 在数据库前端,确保表格尽可能裸露。 在索引之前关闭所有索引并加载数据。

SqlBulkCopy ROCKS。 我用它将30分钟的function变为4秒。 但是,这仅适用于MS SQL Server 。

我建议你看一下你创建的桌子上的约束吗? 如果删除数据库上的所有键,约束等,数据库将对您的插入执行较少的工作,并减少递归工作。

其次,设置具有较大初始大小的表,以防止在插入空白数据库时resize。

最后看看是否有MySQL的批量复制样式API。 SQL Server基本上格式化数据,因为它将下载到磁盘,SQL服务器将流链接到磁盘并且您输入数据。 然后,它会对所有数据执行一次一致性检查,而不是每次插入一次,从而显着提高性能。 祝好运 ;)

你需要MySQL吗? 如果使用Visual Studio并且数据库性能/大小较低,SQL Server可以使您的工作更轻松。

这有帮助吗? 它是一个存储过程,它将整个XML文件加载到列中,然后使用XPath对其进行解析并创建表/从中插入数据。 看起来有点疯狂,但它可能会奏效。

不是你想要的答案,但mysql c api有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的LOAD DATA ,然后重新创建索引/触发器。 我使用这种技术在大约10分钟内将5 GB的论坛数据提取到PostgreSQL数据库中。

当然,这可能不适用于MySQL,但它值得一试。 此外, 这个SO问题的答案表明,这实际上是MySQL可行的策略。

一个快速谷歌提出了一些提高MySQL的LOAD DATA性能的技巧。