【发布时间】:2015-10-16 00:27:54
【问题描述】:
下面是这样的场景:我有一个 500GB 大小的 XML 文件,其中包含大约 6 亿行的数据(一次在数据库表上)。我正在使用 SSIS 进行操作,因为如果我要使用 SSIS 组件(即:XML Source)它会消耗大量内存,它可能会导致超时(如果我错了,请纠正我,但是据我所知,使用 SSIS 上的组件会将 XML 的内容加载到内存中 - 文件那么大肯定会导致错误)。我的做法是:
- 使用
Script Task使用 XML Reader 解析 XML 数据(到目前为止,XML Reader 是最好的方法,因为它以转发、非缓存的方法解析 XML) - 在
DataTable上插入数据 -
DataTable上的每500,000行,使用SqlBulkCopy将内容插入数据库,然后清除DataTable的内容
我的问题是,目前,我尝试用它解析另一个大小为 200GB 的文件,它的运行速度约为 13.5M / 1 小时 - 我不知道它是否仍然适用于该运行时间。它确实解决了我的问题 - 但它并不太优雅,我的意思是,应该有其他方法。
我正在寻找其他方法,例如:
- 将大型 XML 文件分成小块 CSV(大约 20GB),然后使用 SSIS
Data Flow task - 每个新行使用
INSERT脚本
你能帮我决定哪个最好吗?或提出任何其他解决方案。
每一个答案都将不胜感激。
编辑
我忘了提 - 我的方法是动态的。我的意思是,有许多表将填充大型 XML 文件。因此,使用脚本组件作为源可能不是那么有用,因为我仍然需要定义输出列。不过还是要试试看。
编辑 2015-07-28
该文件来自我们的客户,对于他们想要发送给我们的来源,我们无能为力。 XML,就是这样。这是我正在使用的 XML 示例:
<?xml version="1.0" encoding="UTF-8"?>
<MFADISDCP>
<ROW>
<INVESTMENT_CODE>DATA</INVESTMENT_CODE>
<DATE_OF_RECORD>DATA</DATE_OF_RECORD>
<CAPITAL_GAIN_DISTR_RATE>DATA</CAPITAL_GAIN_DISTR_RATE>
<INCOME_DISTR_RATE>DATA</INCOME_DISTR_RATE>
<DISTR_PAYMENT_DATE>DATA</DISTR_PAYMENT_DATE>
<CURRENCY>DATA</CURRENCY>
<CONFIRM>DATA</CONFIRM>
<EXPECTED_DISTRIBUTION_AMOUNT>DATA</EXPECTED_DISTRIBUTION_AMOUNT>
<KEYING_STATUS>DATA</KEYING_STATUS>
<DAF_RATE>DATA</DAF_RATE>
<INCOME_START_DATE>DATA</INCOME_START_DATE>
<ALLOCABLE_END_DATE>DATA</ALLOCABLE_END_DATE>
<TRADE_DATE>DATA</TRADE_DATE>
<OVR_CAPITAL_GAIN_DISTR_OPTION>DATA</OVR_CAPITAL_GAIN_DISTR_OPTION>
<OVR_INCOME_DISTR_OPTION>DATA</OVR_INCOME_DISTR_OPTION>
<BACKDATED_DISTRIBUTION>DATA</BACKDATED_DISTRIBUTION>
<DATE_MODIFIED>DATA</DATE_MODIFIED>
</ROW>
<!--AROUND 49M+ OF THIS ROWS-->
</MFADISDCP>
【问题讨论】:
-
您可以有一个带有脚本组件的单个数据流任务,该脚本组件只是将数据直接流式传输到批量大小为 500,000 的批量加载目标。
-
@MartinSmith - 请查看我对这个问题的更新。
-
解决瓶颈问题。它很可能是您的 XML 粉碎机,但也可能是……网络、内存、磁盘、数据库中的争用(您有排他锁吗?)。源必须是 XML 吗?例如,我建议您将其预先分解为 CSV,然后将其上传,您可能会发现 XML>CSV 比 CSV>Database 花费的时间要长得多
-
在考虑将数据存储在文件中时,请考虑存储结构的开销。对于您拥有的每个元素,最精简的 XML 将花费 7 字节的存储空间。几百行,地狱,几十万行,那罪孽并不可怕。十亿行虽然是站不住脚的。根据存储的内容,您可能会在结构上花费四分之一到一半的存储成本。也许您不关心存储成本,但还有读取访问成本。如果可以将我的 IOPS 从 500GB 降低到 375GB,我读取 EOF 的时间从 ~3 小时到 2.2 @ 50MB/s
-
您可以在这里看到许多不将源存储为 XML 的原因。目前尚不清楚是否可以更改它。你能澄清一下吗?特别是当您说该文件有 52 列和 49M+ 行时……那是表格数据。以 XML(一种详细的树格式)存储表格数据是没有意义的。如果您必须以花哨的格式存储,JSON 是一种树结构并且需要较少的字符来存储。我再次建议您对 XML 粉碎机(脚本任务,但不提供任何内容)进行计时,并查看该部分需要多长时间。我再次问:为什么需要 XML?您是否以分层格式获取数据?
标签: c# sql sql-server xml ssis