我有两张桌子T_A
和T_B
.
- 两者都是空的。
- 两者都有聚集索引。
- 恢复模式设置为
SIMPLE
。 - insert...select.. 满足最小日志记录的要求。请参阅 http://msdn.microsoft.com/en-us/library/ms191244.aspx
- 两个临时表都包含大量数据。
我需要从临时表中将数据导入其中。
如果我单独执行以下 T-SQL 块,每个需要 2 到 3 分钟才能完成。总时间约为 5 到 6 分钟。
BEGIN TRAN
INSERT INTO T_A WITH(TABLOCK) FROM SRC_A WITH(NOLOCK);
COMMIT TRAN
BEGIN TRAN
INSERT INTO T_B WITH(TABLOCK) FROM SRC_B WITH(NOLOCK);
COMMIT TRAN
为了让它更快,我在 SMSS 中打开两个会话并并行执行这两个块。令我惊讶的是,每节课大约需要 10 到 12 分钟才能完成。加起来总时间增加了一倍多。wait_type
显示的是指向PAGEIOLATCH_SH
磁盘 I/O 瓶颈的位置。我不明白的是,即使两个会话必须相互等待 I/O,也不应该等待那么久。谁能帮忙解释一下?
我的故事到这里还没有结束。然后我删除了两个表上的聚集索引,并在不同的会话中并行运行了两个块。这一次每次大约需要 1 分钟才能完成。由于它们是并行的,因此总时间约为 1 分钟。伟大的!但是当我尝试重新创建聚集索引时,噩梦就来了。
如果我单独创建集群索引,则每个需要 4 分钟才能完成。总时间约为8分钟。这违背了我提高性能的目的。
然后我尝试在两个表上并行创建聚集索引,每个表在不同的会话上。这一次是最糟糕的:一个需要 12 分钟才能完成,另一个需要 25 分钟才能完成。
从我的测试结果来看,我最好的选择是回到第一方:使用表上的聚集索引顺序执行两个事务。
有没有人遇到过类似的情况,最好的做法是什么?