An XPath query is executed slowly when referencing the parent node using .. /../<node name>
I want to get all read nodes and their values from each session in my XML document, and also get the session identifier from the parent node. I am running this on an instance of SQL Server 2008.
My xml setup:
<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>
My initial attempt (which works) was shown below, however it seems very slow when I run it. However, when I take out a line that adds SessionID ie./../SessionID, it works much faster. It takes a request for 12 seconds to two seconds.
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)
In any case, I can do this without having to reference the SessionID using the notation .. /../. I need a SessionID, as this query is used to insert records into a temporary table:
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)
+3
1
../../ 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)
+4