Analyse XML lente

8

J'essaie actuellement de régler une procédure stockée quelque peu problématique et j'ai remarqué que la majorité des coûts associés à son exécution proviennent de l'analyse syntaxique de XML dans une table temporaire. Voici le SQL en question:

CREATE TABLE #ChangeSet 
(
    RemarkTypeID TINYINT NOT NULL PRIMARY KEY,
    RemarkText VARCHAR(2500) NOT NULL,
    ListingID INT NOT NULL
)
INSERT INTO #ChangeSet
    (RemarkTypeID, 
    RemarkText,
    ListingID)
SELECT
    T.c.value('@RemarkTypeID[1]','tinyint') AS RemarkTypeID,
    T.c.value('@RemarkText[1]','varchar(2500)') AS RemarkText,
    @ListingID
FROM @RemarksXml.nodes('/Remarks[1]/Remark') AS T(c)

De plus, vous avez donc une idée de la structure du XML analysé:

  <Remarks>
    <Remark xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" RemarkID="211767" DateTimeCreated="1991-11-19T10:43:50" DateTimeModified="1992-01-01T10:43:50" RemarkTypeID="8" RemarkText="aaaWasher,Dryer,Refriger,Microwav" />
    <Remark xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" RemarkID="211768" DateTimeCreated="1991-11-19T10:43:50" DateTimeModified="1992-01-01T10:43:50" RemarkTypeID="3" RemarkText="aaaell Maintained 3Bd 1.5Ba Semi-Detached Home In Cambridge Gardens. Garage W As Converted Into A Nice Family Room The Outside Is Maintence Free. Includes All Appliances,Security System,Storage Shed,Ceiling Fans And New Carpet.This Home Is Very Well Pricded. Seller Will Consider Fha Or Va Along With Conventional Finacing. This Is A Great Buy." />
 </Remarks>

Puis-je faire quelque chose pour améliorer les performances de l'analyse de ces nœuds XML et la configuration de cette table temporaire?

jdm5310
la source
Le XML est-il passé en tant que paramètre?
World Wide DBA
3
Quelle est la taille de votre XML, combien de nœuds de «demande» existe-t-il et à quel point est-il lent? Le coût d'une requête XML est inutile et ne vous dit rien sur les performances réelles.
Mikael Eriksson

Réponses:

5

Tu pourrais essayer OPENXML. Maintenant, je ne recommande normalement pas OPENXMLcar il a un certain nombre de problèmes de mémoire bien connus (en gros, cela peut prendre 1/8 de votre pool de tampons en fonction de la taille de XML) (!! TODO add link). Quelle que soit la légende, il est plus rapide pour les plus gros morceaux de XML, donc cela vaut la peine d'essayer dans un environnement de développement / test et si vous connaissez les problèmes de mémoire et que vous obtenez les performances, c'est à vous de décider de ce dont vous avez le plus besoin. Quelque chose comme ça:

DECLARE @handle INT

EXEC sp_xml_preparedocument @handle OUTPUT, @RemarksXml

INSERT INTO #ChangeSet
SELECT RemarkTypeID, RemarkText, @ListingID
FROM OPENXML( @handle, '/Remarks[1]/Remark', 1 ) 
WITH ( 
    RemarkTypeID    TINYINT,
    RemarkText      VARCHAR(2500)
    )

EXEC sp_xml_removedocument @handle

N'oubliez pas de toujours appeler sp_xml_removedocument. Je suppose que votre vrai XML est beaucoup plus grand, pouvez-vous nous donner une idée du nombre d' Remarkéléments qu'il comportera et de sa taille en Ko / Mo. Je reviendrai plus tard sur le post et mettrai en place un banc d'essai pour comparer les performances en fonction de vos statistiques.

MISE À JOUR: Selon votre exemple de script, votre XML ne peut avoir qu'un maximum de 256 Remarkéléments avec une longueur maximale de 2500. Après avoir créé un exemple de XML pour répondre à ces critères et l'avoir testé, il y a peu de performances entre les deux techniques, et les deux terminer en moins d'une seconde. Dans ce cas, je choisirais le type de données XML et les méthodes. Pouvez-vous fournir les autres informations demandées s'il vous plaît?

wBob
la source
3
SQL Server utilise MSXML et le DOM pour traiter les documents que vous chargez via sp_xml_preparedocument. Il limite la mémoire virtuelle que MSXML peut utiliser pour le traitement DOM à un huitième de la mémoire physique de la machine ou à 500 Mo, selon la valeur la moins élevée .
Paul White 9
4

Il y a deux choses principales que vous pouvez faire pour améliorer les performances d'analyse XML:

  • Faites la variable / colonne xml tapée , ce qui signifie déclarer un schéma xsd dessus. Cela forcera une validation du xml, ce qui en soi prendra un peu de temps, mais la vitesse d'analyse s'améliorera.
  • Indexez une colonne xml (ne s'applique pas aux variables xml). Vous pouvez indexer des colonnes xml de différentes manières, selon vos besoins. Cela peut vous donner d'excellents gains de performances pour les requêtes et les recherches plus complexes dans les objets blob xml.
  • Si votre requête fait partie d'une requête beaucoup plus grande, je semble me souvenir que les opérations xml ne se parallélisent pas, vous pouvez donc judicieusement fractionner une grande requête et effectuer l'analyse XML dans une requête distincte du reste du travail.
Daniel Hutmacher
la source
3
Je compte cependant trois choses. :-)
Aaron Bertrand