sql >> Databasteknik >  >> RDS >> Database

XML-prestandatips

Att analysera data från XML med XQuery är rutinmässigt. För att göra detta mest effektivt krävs lite ansträngning.

Anta att vi behöver analysera data från diskfilen med följande struktur:

<tables>
<table name="Accounting" schema="Production" object="Accounting">
<column name="Date" order="3" visible="1" />
<column name="DateFrom" order="5" visible="1" />
<column name="DateTo" order="6" visible="1" />
<column name="Description" order="4" visible="1" />
<column name="DocumentUID" order="1" visible="0" />
<column name="Number" order="2" visible="1" />
<column name="Warehouse" order="7" visible="1" />
</table>
</tables>

Använd BULK INSERT om du behöver läsa data från en fil:

SELECT BulkColumn
FROM OPENROWSET(BULK 'D:\data.xml', SINGLE_BLOB) x sample xml file

Ett exempel på en xml-fil finns här.

Kom dock ihåg en sak... Försök att inte läsa informationen direkt:

;WITH cte AS
(
SELECT x = CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK 'D:\data.xml', SINGLE_BLOB) x
)
SELECT t.c.value('@name', 'VARCHAR(100)')
FROM cte
CROSS APPLY x.nodes('tables/table') t(c)

Tilldela data till en variabel. På så sätt kan du få en mer effektiv genomförandeplan:

DECLARE @xml XML
SELECT @xml = BulkColumn
FROM OPENROWSET(BULK 'D:\data.xml', SINGLE_BLOB) x

SELECT t.c.value('@name', 'VARCHAR(100)')
FROM @xml.nodes('tables/table') t(c)

Jämför resultaten:

Table 'Worktable'. Scan count 0, logical reads 729, physical reads 0, read-ahead reads 0, lob logical reads 62655,...
SQL Server Execution Times:
CPU time = 1203 ms, elapsed time = 1214 ms.

Table 'Worktable'. Scan count 0, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 202,....
SQL Server Execution Times:
CPU time = 16 ms, elapsed time = 4 ms.

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 3 ms.

Som du kan se är det andra alternativet betydligt snabbare.

En annan viktig egenskap hos SQL Server när du arbetar med XQuery är att läsning av ett överordnat element kan resultera i dålig prestanda. Tänk på följande exempel:

SET STATISTICS PROFILE OFF

DECLARE @xml XML
SELECT @xml = BulkColumn
FROM OPENROWSET(BULK 'D:\data.xml', SINGLE_BLOB) x

SET STATISTICS PROFILE ON

SELECT
t.c.value('@name', 'SYSNAME')
, t.c.value('@order', 'INT')
, t.c.value('@visible', 'BIT')
, t.c.value('../@name', 'SYSNAME')
, t.c.value('../@schema', 'SYSNAME')
, t.c.value('../@object', 'SYSNAME')
FROM @xml.nodes('tables/table/*') t(c)

Låt oss titta på det faktiska antalet rader som tas emot från operatören. Värdet är onormalt stort:

Förfrågan kan enkelt optimeras med hjälp av CROSS APPLY:

SELECT
t2.c2.value('@name', 'SYSNAME')
, t2.c2.value('@order', 'INT')
, t2.c2.value('@visible', 'BIT')
, t.c.value('@name', 'SYSNAME')
, t.c.value('@schema', 'SYSNAME')
, t.c.value('@object', 'SYSNAME')
FROM @xml.nodes('tables/table') t(c)
CROSS APPLY t.c.nodes('column') t2(c2)

Låt oss jämföra exekveringstiden:

(1408 row(s) affected)
SQL Server Execution Times:
CPU time = 10125 ms, elapsed time = 10135 ms.

(1408 row(s) affected)
SQL Server Execution Times:
CPU time = 78 ms, elapsed time = 156 ms.

Som du kan se i exemplet fungerar begäran med CROSS APPLY direkt.

Tack för din uppmärksamhet. Jag hoppas att den här artikeln var användbar. Ställ gärna några frågor, lämna dina kommentarer och förslag angående den här artikeln.


  1. SQL BESTÄLLNING EFTER:De 5 bör och inte göra för att sortera data som ett proffs

  2. Biblioteket har inte laddats:libmysqlclient.16.dylib fel vid försök att köra 'rails server' på OS X 10.6 med mysql2 gem

  3. Använda MySQLi för att INFOGA data i en databas

  4. Förstå vikten av minnesinställning i SQL Server