sql >> Database >  >> RDS >> Sqlserver

XML Server Optimalisatie van XML-prestaties

Ik kan je één antwoord geven en één keer raden:

Eerst gebruik ik een gedeclareerde tabelvariabele om te mock-up jouw scenario:

DECLARE @tbl TABLE(s NVARCHAR(MAX));
INSERT INTO @tbl VALUES
(N'<root>
    <SomeElement>This is first text of element1
        <InnerElement>This is text of inner element1</InnerElement>
        This is second text of element1
    </SomeElement>
    <SomeElement>This is first text of element2
        <InnerElement>This is text of inner element2</InnerElement>
        This is second text of element2
    </SomeElement>
</root>')
,(N'<root>
    <SomeElement>This is first text of elementA
        <InnerElement>This is text of inner elementA</InnerElement>
        This is second text of elementA
    </SomeElement>
    <SomeElement>This is first text of elementB
        <InnerElement>This is text of inner elementB</InnerElement>
        This is second text of elementB
    </SomeElement>
</root>');

--Deze query zal de XML lezen met een cast-out van een sub-select . U kunt een CTE . gebruiken in plaats daarvan, maar dit zou alleen syntactische suiker moeten zijn...

SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
      ,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
      ,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
      ,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
FROM (SELECT CAST(s AS XML) FROM @tbl) AS tbl(TheXml)
CROSS APPLY TheXml.nodes(N'/root/SomeElement') AS A(se);

--Het tweede deel gebruikt een tabel om in de getypte XML te schrijven en van daaruit te lezen:

DECLARE @tbl2 TABLE(x XML)
INSERT INTO @tbl2
SELECT CAST(s AS XML) FROM @tbl;

SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
      ,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
      ,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
      ,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
FROM @tbl2 t2
CROSS APPLY t2.x.nodes(N'/root/SomeElement') AS A(se);

Waarom is /text() sneller dan zonder /text() ?

Als je naar mijn voorbeeld kijkt, is de inhoud van een element alles van de openingstag tot de sluitingstag . De text() van een element is de zwevende tekst tussen deze labels. U kunt dit zien in de resultaten van de selectie hierboven. De text() is een afzonderlijk opgeslagen gedeelte in een boomstructuur eigenlijk (lees volgende paragraaf). Om het op te halen, is een eenstapsactie . Anders moet een complexe structuur worden geanalyseerd om alles te vinden tussen de openingstag en de bijbehorende sluitingstag - zelfs als er niets anders is dan de text() .

Waarom zou ik XML in het juiste type opslaan?

XML is niet alleen tekst met een paar gekke extra karakters! Het is een document met een complexe structuur. De XML wordt niet opgeslagen als de tekst die u ziet . XML wordt opgeslagen in een boomstructuur. Telkens wanneer u een string, die een XML vertegenwoordigt, in een echte XML cast, moet dit zeer dure werk worden gedaan. Wanneer de XML aan u wordt gepresenteerd (of een andere uitvoer), wordt de representerende string helemaal opnieuw opgebouwd.

Waarom is de vooraf gegoten aanpak sneller

Dit is gissen...
In mijn voorbeeld zijn beide benaderingen vrij gelijk en leiden ze tot (bijna) hetzelfde uitvoeringsplan.
SQL Server zal niet alles afwerken zoals je dit zou verwachten. Dit is geen procedureel systeem waarbij je zegt doe dit, doe dit en daarna dit! . Jij vertelt de motor wat je wilt, en de motor bepaalt hoe hij dit het beste kan doen. En de engine is hier best goed in!
Voordat de uitvoering begint, probeert de engine de kosten van naderingen in te schatten. CONVERT (of CAST ) is een vrij goedkope operatie. Het kan zijn dat de engine besluit om de lijst met je oproepen af ​​te werken en de cast voor elke afzonderlijke behoefte keer op keer uit te voeren, omdat hij denkt dat dit goedkoper is dan het dure maken van een afgeleide tabel...




  1. Hoe sql*plus te gebruiken in het Windows-opdrachtscript om de stroom te regelen?

  2. Best practices voor het ontwerpen van meertalige databases

  3. Hoe REGEXP_SUBSTR() werkt in MariaDB

  4. Cheatsheet voor MySQL-prestaties