12

问题

将大型(> 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”这样的特性在这个项目中是不可用的,因为这个特性只在 MySQL 5.4 及更高版本中可用。这个限制主要是因为我希望这个项目对我以外的人有用,我不想强​​迫人们使用 MySQL 的 Beta 版本。
  • 我希望将数据加载内置到我的应用程序中(即没有说明“在运行此应用程序之前使用 'foo' 将转储加载到 MySQL 中。”)。
  • 我正在使用 MySQL 连接器/网络,因此MySql.Data命名空间中的任何内容都是可以接受的。

感谢您提供的任何指示!


到目前为止的想法

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

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

8 回答 8

12

这有两个部分:

  • 读取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。总时间可能少于您体验的小时数。

于 2009-09-24T17:45:38.887 回答
1

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

为什么要放在数据库中?

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

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

于 2009-09-28T21:03:02.453 回答
1

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

  1. The size of the query may need to be tweaked, there's often a point where the big statement costs more in parsing time and so becomes slower. The 500 may be optimal, but perhaps it is not and you could tweak that a little (it could be more, it could be less).

  2. Go multithreaded. Assuming your system isn't already flatlined on the processing, you could make some gains by having breaking up the data in to chunks and having threads process them. Again, it's an experimentation thing to find the optimal number of threads, but a lot of people are using multicore machines and have CPU cycles to spare.

  3. On the database front, make sure that the table is as bare as it can be. Turn off any indexes and load the data before indexing it.

于 2009-09-29T01:09:41.893 回答
1

SqlBulkCopy ROCKS。我用它把一个 30 分钟的功能变成了 4 秒。但是,这仅适用于 MS SQL Server

我可以建议您查看您创建的表上的约束吗?如果您删除数据库上的所有键、约束等,数据库将减少您的插入工作和递归工作。

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

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

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

于 2009-09-29T01:18:46.390 回答
0

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

于 2009-09-21T19:23:11.257 回答
0

不是你想要的答案,但是 mysql c api 有mysql_stmt_send_long_data函数。

于 2009-09-24T17:25:13.967 回答
0

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

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

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

于 2009-09-26T07:29:59.923 回答
0

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

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

一个快速的谷歌出现了一些关于提高 MySQL 的 LOAD DATA 性能的提示。

于 2009-09-29T23:40:32.260 回答