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

时间:2009-09-21 18:37:00

标签: c# mysql xml load-data-infile

问题

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

数据

有问题的数据是StackOverflow知识共享数据转储。

目的

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

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

问题

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

约束

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

感谢您提供的任何指示!


到目前为止的想法

  

将整个XML文件加载到列中的存储过程,然后使用XPath

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

8 个答案:

答案 0 :(得分:12)

这有两个部分:

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

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

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

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

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

答案 1 :(得分:1)

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

  

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

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

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

答案 2 :(得分:1)

我有一些想法可以帮助加快速度......

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

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

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

答案 3 :(得分:1)

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

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

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

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

不是您想要的答案,但mysql c api具有mysql_stmt_send_long_data功能。

答案 6 :(得分:0)

我在上面的一条评论中注意到你正在考虑MSSQL,所以我想我会发布这个。 SQL Server有一个名为SQMLXMLBulkLoad的实用程序,用于将大量XML数据导入SQL Server数据库。以下是SQL Sever 2008版本的文档:

http://msdn.microsoft.com/en-us/library/ms171993.aspx

早期版本的SQL Server也有此实用程序

答案 7 :(得分:0)

PostgreSQL中,获取批量数据的绝对最快方法是删除所有索引和触发器,使用等效的MySQL LOAD DATA,然后重新创建索引/触发器。我使用这种技术在大约10分钟内将5 GB的论坛数据提取到PostgreSQL数据库中。

当然,这可能不适用于MySQL,但它值得一试。此外,this SO question's answer表明这实际上是MySQL的可行策略。

快速谷歌提出了increasing the performance of MySQL's LOAD DATA的一些提示。