Ich habe eine Tabelle mit vielen großen XML-Dokumenten.
Wenn ich xpath-Ausdrücke ausführe, um Daten aus diesen Dokumenten auszuwählen, tritt ein besonderes Leistungsproblem auf.
Meine Anfrage ist
SELECT
p.n.value('.', 'int') AS PurchaseOrderID
,x.ProductID
FROM XmlLoadData x
CROSS APPLY x.PayLoad.nodes('declare namespace NS="http://schemas.datacontract.org/2004/07/XmlDbPerfTest";
/NS:ProductAndRelated[1]/NS:Product[1]/NS:PurchaseOrderDetails[1]/NS:PurchaseOrderDetail/NS:PurchaseOrderID[1]') p(n)
Die Abfrage dauert 2 Minuten und 8 Sekunden.
Wenn ich die [1]
Teile der einzelnen Vorkommensknoten wie folgt entferne :
SELECT
p.n.value('.', 'int') AS PurchaseOrderID
,x.ProductID
FROM XmlLoadData x
CROSS APPLY x.PayLoad.nodes('declare namespace NS="http://schemas.datacontract.org/2004/07/XmlDbPerfTest";
/NS:ProductAndRelated/NS:Product/NS:PurchaseOrderDetails/NS:PurchaseOrderDetail/NS:PurchaseOrderID') p(n)
Die Ausführungszeit sinkt auf nur 18 Sekunden.
Da die [1]
-knoten in jedem übergeordneten Knoten in den Dokumenten nur einmal vorkommen, sind die Ergebnisse bis auf die Reihenfolge gleich.
Der tatsächliche Ausführungsplan für die erste (langsame) Abfrage lautet
und die zweite (schnellere) Abfrage ist
Abfrage 1 Vollbild Abfrage 2 Vollbild .
Soweit ich sehen kann, führt die Abfrage mit [1]
dieselbe Ausführung aus wie die Abfrage ohne, jedoch mit einigen zusätzlichen Berechnungsschritten, um das erste Element zu finden.
Meine Frage ist, warum die zweite Abfrage schneller ist.
Ich hätte erwartet, dass die Ausführung der Abfrage mit [1]
vorzeitig unterbrochen wird , wenn eine Übereinstimmung gefunden wird, und somit die Ausführungszeit anstelle des Gegenteils verkürzt.
Gibt es Gründe, warum die Ausführung nicht vorzeitig unterbrochen wird [1]
und somit die Ausführungszeit verkürzt wird?
Das ist mein Tisch
CREATE TABLE [dbo].[XmlLoadData](
[ProductID] [int] NOT NULL,
[PayLoad] [xml] NOT NULL,
[Size] AS (len(CONVERT([nvarchar](max),[PayLoad],0))),
CONSTRAINT [PK_XmlLoadData] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Bearbeiten:
Leistungszahlen aus SQL Profiler:
Abfrage 1:
CPU Reads Writes Duration
126251 1224892 0 129797
Abfrage 2:
CPU Reads Writes Duration
50124 612499 0 16307