Was ist schneller .exist oder .value in einer where-Klausel?

Ich mache einige grobe Benchmarks mit dem XML-datatyp von SQL server 2008. Ich habe viele Orte gesehen, wo .exist in where Klauseln verwendet wird. Ich habe vor kurzem zwei Abfragen verglichen und bekam seltsame Ergebnisse.

 select count(testxmlrid) from testxml where Attributes.exist('(form/fields/field)[@id="1"]')=1 

Diese Abfrage dauert etwa 1,5 Sekunden, um zu laufen, ohne Indizes auf alles andere als den Primärschlüssel (testxmlrid)

 select count(testxmlrid) from testxml where Attributes.value('(/form/fields/field/@id)[1]','integer')=1 

Diese Abfrage auf der anderen Seite dauert ca. .75 Sekunden zu laufen.

Ich verwende untypisiertes XML und mein Benchmarking findet auf einer SQL server 2008 Express Instanz statt. Es gibt etwa 15.000 Zeilen im datasatz und jeder XML-String ist etwa 25 Zeilen lang.

Sind diese Ergebnisse richtig? Wenn ja, warum benutzt jeder .exist ? Bin ich etwas falsches und .exist könnte schneller sein?

Sie zählen nicht die gleichen Dinge. Ihre .exist Abfrage (form/fields/field)[@id="1"] prüft alle Vorkommen von @id im XML, bis sie mit dem Wert 1 und Ihrer .value Abfrage (/form/fields/field/@id)[1] holt nur das erste Vorkommen von @id .

Testen Sie dies:

 declare @T table ( testxmlrid int identity primary key, Attributes xml ) insert into @T values ('<form> <fields> <field id="2"/> <field id="1"/> </fields> </form>') select count(testxmlrid) from @T where Attributes.exist('(form/fields/field)[@id="1"]')=1 select count(testxmlrid) from @T where Attributes.value('(/form/fields/field/@id)[1]','integer')=1 

Die .exist ist 1, weil sie die @id=1 im zweiten .value und die .value 0 ist, da sie nur den Wert für das erste Vorkommen von @id überprüft.

Eine .exist Abfrage, die nur den Wert für das erste Vorkommen von @id wie Ihre .value Abfrage .value würde so aussehen.

 select count(testxmlrid) from @T where Attributes.exist('(/form/fields/field/@id)[1][.="1"]')=1 

Der Unterschied könnte aus Ihren Indizes kommen.

Ein PATH Index wird die performance des exist() Prädikats) auf der WHERE Klausel erhöhen, während ein PROPERTY Index die Performance der function value() steigert.

Lesen: http://msdn.microsoft.com/en-us/library/bb522562.aspx