【发布时间】:2014-11-08 10:54:18
【问题描述】:
我正在尝试将大约 2500 万行从 Azure SQL 表批量加载到 Azure 表存储中的三个不同表中。我目前正在设法处理大约 50-100 行/秒,这意味着在当前速度下,我需要大约 70-140 小时才能完成负载。时间很长,看来应该可以加快速度。
这就是我正在做的事情:
- 开始 10 个单独的任务
- 对于每个任务,从 SQL 数据库中读取接下来的 10,000 条未处理记录
- 对于三个目标 ATS 表中的每一个,按该表的分区键对 10,000 条记录进行分组
- 并行(最多同时 10 个),对于每个分区键,将分区分成(最多)100 行段
- 并行(最多同时 10 个),为每个段创建一个新的
TableBatchOperation。 - 对于块中的每一行,执行一个batch.InsertOrReplace() 语句(因为有些数据已经加载了,我不知道是哪个)
- 异步执行批处理
- 冲洗并重复(有大量的流量控制、错误检查等)
一些注意事项:
- 我已经尝试了几种不同的方法,上面的各种数字有很多不同的参数,但我仍然没有将其降低到小于 10-20 毫秒/事件。
- 它似乎不受 CPU 限制,因为执行负载的 VM 平均占用大约 10-20% 的 CPU。
- 它似乎不受 SQL 限制,因为 SQL 选择语句是操作中最快的部分,至少快了两个数量级。
- 它可能不受网络限制,因为执行批处理的 VM 位于同一个数据中心(美国西部)。
- 我得到了合理的分区密度,即每 10K 组记录被分解为每个表的几百个分区。
- 有了完美的分区密度,我可以同时运行多达 3000 个任务(10 个主任务 * 3 个表 * 10 个分区 * 10 个段)。但它们是异步执行的,而且它们几乎都受 I/O 限制(受 ATS 限制),所以我认为我们在执行进程的 VM 上没有达到任何线程限制。
我能想出的唯一另一个明显的想法是我之前尝试过的一个,即在 SQL 选择语句中创建一个order by 分区键,以便我们可以为批量插入获得完美的分区密度。由于各种原因,这已被证明是困难的,因为表的索引并没有为此设置好。虽然我希望使用该方法在 ATS 端一些加速,但鉴于我已经按分区键对 10K 记录进行分组,我不希望获得那么多额外的性能改进.
还有其他加快速度的建议吗?或者这与其他人所能达到的速度一样快?
【问题讨论】:
-
此链接应该为您提供您正在寻找的信息leiliweb.wordpress.com/2012/12/11/…
-
@J.Davidson - 感谢您的建议,但它谈到了 SQL Server 的分区策略,我在使用 Azure 表存储时遇到了问题。相当不同的野兽:-)。