使用../../ <node name =“”> </node>引用父节点时,XPath查询运行缓慢

时间:2012-05-09 22:19:10

标签: sql xpath performance

我希望从我的xml文档中的每个会话中获取所有读取节点及其值,以及从父节点获取会话ID。我在SQL Server 2008实例上运行它。

我的xml设置是:

<Sessions>
<SessionID>99</SessionID>
<Readings>
  <Reading>
    <Point>
      <Lat>-40.411558</Lat>
      <Lng>175.63504</Lng>
    </Point>
    <Heading>54</Heading>
    <Speed>0.1</Speed>
    <Height>0</Height>
    <FlowRate>0.69</FlowRate>
    <AppRate>74</AppRate>
  </Reading>
  ... more readings
</Readings>
<Sessions>

我的原始尝试(有效)如下所示,但是当我运行它时,这似乎非常慢。然而,当我拿出添加SessionID的行,即../../SessionID时,它的执行速度似乎要快得多。这需要12秒的查询,只需2秒。

        SELECT
            [SessionID] = c.value('(../../SessionID)[1]', 'int'),
            [Heading] = c.value('(Heading)[1]', 'float'),
            [Speed] = c.value('(Speed)[1]', 'float'),
            [Height] = c.value('(Height)[1]', 'float'),
            [FlowRate] = c.value('(FlowRate)[1]', 'float'),
            [AppRate] = c.value('(AppRate)[1]', 'float'),
            [Latitude] = c.value('(Point/Lat)[1]', 'float'),
            [Longtitude] = c.value('(Point/Lng)[1]', 'float')
        FROM
            @XMLData.nodes('/Sessions/Readings/Reading') XMLData(c)

无论如何,我可以在不需要使用../../表示法引用SessionID的情况下执行此操作。我确实需要SessionID,因为此查询用于将记录插入临时表:

insert into #MyTempTable
SELECT
            [SessionID] = c.value('(../../SessionID)[1]', 'int'),
            [Heading] = c.value('(Heading)[1]', 'float'),
            [Speed] = c.value('(Speed)[1]', 'float'),
            [Height] = c.value('(Height)[1]', 'float'),
            [FlowRate] = c.value('(FlowRate)[1]', 'float'),
            [AppRate] = c.value('(AppRate)[1]', 'float'),
            [Latitude] = c.value('(Point/Lat)[1]', 'float'),
            [Longtitude] = c.value('(Point/Lng)[1]', 'float')
        FROM
            @XMLData.nodes('/Sessions/Readings/Reading') XMLData(c)

1 个答案:

答案 0 :(得分:4)

对于避免../../的第一部分,您可以使用CROSS APPLY来提供两个数据集。

此外,如果您想要更快的INSERT并且不担心日志记录,那么SELECT INTO语句将提供更快的插入:

SELECT
    s.value('(SessionID)[1]', 'int') SessionID,             
    r.value('(Heading)[1]', 'float') Heading,
    r.value('(Speed)[1]', 'float') Speed,
    r.value('(Height)[1]', 'float') Height,
    r.value('(FlowRate)[1]', 'float') FlowRate,
    r.value('(AppRate)[1]', 'float') AppRate,
    r.value('(Point/Lat)[1]', 'float') Latitude,
    r.value('(Point/Lng)[1]', 'float') Longtitude
INTO #Reading
FROM
    @XMLData.nodes('/Sessions') as S(s)
    CROSS APPLY 
    s.nodes('./Readings/Reading') XMLData(r)