我有一张表,我将用昂贵的计算值(使用来自不可变XML列的xquery)填充值。为了加速部署到生产,我已经在测试服务器上预先计算了值,并将其保存到带有BCP的文件中。按顺序运行时SQL查询速度慢,但在单独运行时速度很快
我的脚本如下
-- Lots of other work, including modifying OtherTable
CREATE TABLE FOO (...)
GO
BULK INSERT FOO
FROM 'C:\foo.dat';
GO
-- rerun from here after the break
INSERT INTO FOO
(ID, TotalQuantity)
SELECT
e.ID,
SUM(e.Quantity) as TotalQuantity
FROM (select
o.ID,
h.n.value('TotalQuantity[1]/.', 'int') as TotalQuantity
FROM dbo.OtherTable o
CROSS APPLY XmlColumn.nodes('(item/.../salesorder/)') h(n)
WHERE o.ID NOT IN (SELECT DISTINCT ID FROM FOO)
) as E
GROUP BY e.ID
当我在Management Studio中的前两行秒钟之内完成运行脚本,但最后的语句需要4个小时才能完成。由于我的foo.dat是计算管理工作室报告(0 row(s) affected)
,因此没有行被添加到OtherTable
。
如果我取消了两三分钟后,查询执行,并选择刚刚过去的查询,并单独运行它在5秒内完成这一点。
值得注意的事实:
- 的OtherTable包含20万行和XmlColumn的数据是相当大的,总表的大小〜3GB
- foo表得到130万行
有什么事情可能会有所作为?
管理工作室关闭了隐式交易。就我所能理解的,每条陈述都会在自己的交易中运行。
更新:
如果我先选择并运行脚本,直到-- rerun from here after the break
,然后选择并运行刚刚过去的查询,它仍然是缓慢的,直到我取消执行,然后再试一次。这至少排除了与脚本中的前一代码“一起”运行的任何效果,并归结为相同的查询在第一次执行时速度慢,在第二次时速度很快(在所有其他条件相同的情况下运行)。
你可以看到在执行计划的任何差异?最后一个陈述需要4个小时,你可以看看估计的计划,而不是实际的(至少是一开始)。 – 2012-01-04 08:12:49
“如果我在几分钟后取消查询执行并仅选择最后一个查询并单独运行,它将在5秒内完成。“ - 你是否自己运行select,将结果插入空foo中或将结果插入到foo中?foo获取大部分来自BCP进程的130M行还是来自OtherTable的插入? – 2012-01-04 08:49:41
@MarkBannister ,我正在运行带有填充表的select,我只是从按下cancel的地方继续使用同一个脚本,所有的1.3M行都来自批量插入(这就是'(0 row(s)affected) '表示)。 – 2012-01-04 09:08:45