INSERT INTO #temp 花费的时间是 SELECT INTO #temp 的 1000 倍

sca*_*cci 4 sql-server sql-server-2008-r2

我正在粉碎传递给我的 xml blob 并加载临时表以进行进一步处理。我在整个过程中注意到的一件事是,执行一个INSERT INTO大约需要 20 分钟,而执行一个SELECT INTO则需要几秒钟。数据库统计数据是最新的,我们正在运行日常维护计划,所以不确定发生了什么。我知道SELECT INTO绕过日志会使其更快,但我不认为INSERT INTO会更糟。

编辑:根据评论添加更多细节

为什么 INSERT INTO 比SELECT INTO临时表花费的时间长得多。

查询示例如下。我正在粉碎 XML 并将其插入到临时表中,我已将INSERT INTOSELECT INTO注释掉。该INSERT INTO仅售100条记录中显示382,000+而逻辑读取SELECT INTO正显示出无法比拟的。

;with cteScen AS (
SELECT    DENSE_RANK() OVER ( ORDER BY scenario_node ) AS scenario ,
        RANK() OVER ( PARTITION BY scenario_node ORDER BY scen_val ) AS level_order ,
        scen_val.value('text-value[1]',
                       'varchar(100)') AS 'scen_value' ,
        scen_val.value('(distribution/@id)[1]',
                       'int') AS 'dist'
FROM      @scenarioXML.nodes('/scenarios/scenario')
        AS scenario ( scenario_node )
        CROSS APPLY scenario.scenario_node.nodes('./values/value')
        AS x ( scen_val ))
--INSERT INTO #tmpTbl(Scenario, Level_Order, Scenario_Value, Distribution_ID)
Select top 100 *
--INTO #tmpTbl
From cteScen
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

Mik*_*son 5

这里有几个可能相关的连接项。

使用 XML.nodes() 的 INSERT 语句在 SQL2008 SP1 中非常非常非常慢
表变量的 xml 性能很差
从以元素为中心的文档插入数据时
性能很差 从 .nodes 中插入基于元素的 XML 在具有 x64 的 SP2 上的性能很差

我无法重现您在查询中看到的内容,因此我无法确定您发生了什么,但一个问题是查询计划中有一个不需要的急切假脱机步骤。可以通过在 SQL Server 的第一个固定版本中使用跟踪标志来删除该 Eager spool。我不确定在以后的版本中是否需要这样做。急切的线轴在那里“由于一般的万圣节保护逻辑”。这可能解释了为什么在插入到现有表时会看到糟糕的性能。如果您查看两个查询的查询计划,您应该会看到差异。

还有一些解决方法建议您可以尝试,我认为您应该尝试在 fetch 时指定文本节点text-value

scen_val.value('(text-value/text())[1]', 'varchar(100)') AS 'scen_value' ,
Run Code Online (Sandbox Code Playgroud)

如果您不这样做,SQL Server 将聚合下面的所有文本值text-value。对于您的 XML,您可能看不到结果的差异,但如果text-value是包含文本和子节点的混合内容节点,您会看到。

declare @XML xml = '
<root>
  <item>item text <subitem>sub item text</subitem>
  </item>
</root>'

select @XML.value('(/root/item)[1]', 'varchar(50)') as C1,
       @XML.value('(/root/item/text())[1]', 'varchar(50)') as C2
Run Code Online (Sandbox Code Playgroud)

结果:

C1                           C2
---------------------------- ----------------------------
item text sub item text      item text 
Run Code Online (Sandbox Code Playgroud)