1

我所在的地方有一个运行在大型 AIX 大型机上的主系统。为了方便报告和操作,每晚都会从大型机转储到 SQL Server,这样我们的 50 多个客户端中的每一个都在具有相同架构的自己的数据库中。这个转储每晚大约需要 7 个小时才能完成,而且我们真的无能为力:我们被应用程序供应商提供的东西所困扰。

转储到 sql server 后,我们使用它来运行许多其他日常程序。其中一个过程是将数据导入一种管理报告沙箱表,该表将来自不同数据库的一个特别重要的表中的记录组合到一个表中,不了解 sql 的管理人员可以使用该表来运行临时报告无需冲洗系统的其余部分。这又是一个商业问题:经理们想要它,他们有权看到我们实施它。

此表的导入过程本身需要几个小时。它将分布在 50 个数据库中的大约 4000 万条记录过滤成大约 400 万条记录,然后在某些列上对它们进行索引以进行搜索。即使在几个小时内,它仍然不到初始负载的三分之一,但是我们已经没有时间进行夜间处理了,我们无法控制大型机转储,我们可以控制它。所以我的任务是寻找改进现有程序的方法。

目前,理念是从每个客户端数据库加载所有数据,然后一步索引它会更快。此外,为了避免在运行时间过长时使其他重要系统陷入困境,一些较大的客户端被设置为始终首先运行(表上的主索引由 clientid 字段组成)。我们开始做的另一件事是一次从几个客户端并行加载数据,而不是顺序加载每个客户端。

所以我的问题是,加载此表的最有效方法是什么?我们是否认为稍后索引更好?还是我们应该在导入数据之前创建索引?我们是否应该按索引顺序加载表,以避免大量重新排序页面,而不是首先加载大客户?并行加载是否会因为一次导致大量磁盘访问或消除我们控制顺序的能力而使事情变得更糟?还有其他想法吗?

更新
嗯,有事。白天我可以做一些基准测试,无论是在操作开始时创建索引还是在操作结束时创建索引,加载时间都没有区别,但是我们节省了构建索引本身的时间(它的课程几乎立即构建,表中没有数据)。

4

4 回答 4

1

索引在最后,是的。还可以考虑将日志级别设置设置为 BULK LOGGED 以尽量减少对事务日志的写入。请记住在完成后将其设置回 FULL。

于 2008-10-22T19:43:16.297 回答
1

我已经在 SQL Server 中加载了大量数据集,并在插入时对索引进行了一些性能测试,然后再添加它。我发现 BY FAR 在加载所有数据后创建索引效率更高。在我们的例子中,加载最后添加的索引需要 1 小时,而在索引仍然打开的情况下添加它需要 4 小时。

我认为关键是尽可能快地移动数据,我不确定按顺序加载它是否真的有帮助,你有关于加载时间与索引时间的统计数据吗?如果你这样做了,你可以开始在这方面进行一些实验。

于 2008-10-22T14:37:04.837 回答
1

加载删除索引会更好,因为实时索引将为数据库中的每一行生成多个 I/O。400 万行足够小,您不会期望从表分区中获得显着的好处。

通过使用 bcp 将数据加载到暂存区域并并行运行多个任务(SSIS 将执行此操作),您可以获得性能优势。为 bcp 编写一个通用批处理文件包装器,该包装器采用文件路径(必要时还包括表名),并在 SSIS 中使用“执行进程”任务在六个线程中调用一系列作业。对于 50 个作业,可能不值得尝试编写数据驱动的负载控制器进程。将这些任务包装在一个序列容器中,这样您就不必显式维护所有依赖项。

您绝对应该删除并重新创建索引,因为这将大大减少该过程中的 I/O 量。

如果 50 个源的处理方式相同,请尝试将它们加载到公用表中或在临时表上构建分区视图。

于 2008-10-22T15:18:47.967 回答
0

据我所知,您是正确的 - 最好一次添加所有记录,然后在最后索引一次。

于 2008-10-22T14:33:48.760 回答