Geschätzte und tatsächliche Zeilenunterschiede (tatsächlich viel kleiner als geschätzt) - Sortierung

8

Ich führe eine Abfrage aus, die einige Knoten aus einem XML-Dokument verarbeitet. Meine geschätzten Teilbaumkosten liegen in Millionenhöhe und es scheint, dass alles von einer Sortieroperation stammt, die der SQL Server für einige Daten ausführt, die ich über XPath aus XML-Spalten extrahiere. Die Sortieroperation hat eine geschätzte Anzahl von Zeilen von ungefähr 19 Millionen, während die tatsächliche Zeilenanzahl ungefähr 800 beträgt. Die Abfrage selbst läuft ziemlich gut (1 - 2 Sekunden), aber die Diskrepanz lässt mich über die Abfrageleistung und warum dies nachdenken Unterschied ist so groß?

Peter Smith
quelle
2
Dies ist möglicherweise auf veraltete Statistiken zurückzuführen, aber ohne weitere Informationen (einschließlich der Tabellenstruktur / -indizes, der Abfrage und eines tatsächlichen - nicht geschätzten - Ausführungsplans) nicht zu erkennen.
Aaron Bertrand
1
Nach meiner Erfahrung haben Abfragepläne, bei denen XML vernichtet wird, immer stark überhöhte Kostenschätzungen. Bis zu dem Punkt, dass ich die Kostenschätzungszahlen einfach ignoriere, wenn die Abfrage in Bezug auf die Ausführungszeit eine gute Leistung erbringt. Ich habe keine Ahnung, warum das so ist, aber es kann etwas damit zu tun haben, nicht zu wissen, wie viel XML als Eingabe verwendet wird. Wenn Ihr Ziel jedoch darin besteht, die Leistung der Abfrage zu verbessern, habe ich eine Möglichkeit gefunden, XML-Schemasammlungen zu verwenden, über die ich hier gebloggt habe .
Jon Seigel

Antworten:

9

Für XML-Spalten werden keine Statistiken generiert. Die Schätzungen werden basierend auf den Ausdrücken erraten, die beim Abfragen des XML verwendet werden.

Verwenden dieser Tabelle:

create table T(XMLCol xml not null)
insert into T values('<root><item value = "1" /></root>')

Und diese ziemlich einfache XML-Abfrage:

select X.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root/item') as X(N)

Sie erhalten eine zurückgegebene Zeile, aber die geschätzten zurückgegebenen Zeilen sind 200. Es sind 200, unabhängig davon, welches XML oder wie viel XML Sie in die XML-Spalte für diese eine Zeile einfügen.

Dies ist der Abfrageplan mit der geschätzten angezeigten Zeilenanzahl.

Geben Sie hier die Bildbeschreibung ein

Eine Möglichkeit, die Schätzungen zu verbessern oder zumindest zu ändern, besteht darin, dem Abfrageoptimierer weitere Informationen zum XML zu geben. In diesem Fall kann ich die Abfrage wie folgt umschreiben , da ich weiß, dass dies rootwirklich ein Stammknoten im XML ist.

select X2.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root[1]') as X1(N)
  cross apply X1.N.nodes('item') X2(N)

Das gibt mir eine Schätzung von 5 zurückgegebenen Zeilen.

Geben Sie hier die Bildbeschreibung ein

Das Umschreiben der Abfrage beschleunigt wahrscheinlich nicht das Shredden des XML. Wenn die Schätzungen jedoch besser sind, kann das Abfrageoptimierungsprogramm möglicherweise intelligentere Entscheidungen für den Rest der Abfrage treffen.

Ich habe keine Dokumentation zu den Regeln für die Schätzungen gefunden, außer einer Präsentation von Michael Rys, in der er sagt:

Die Schätzung der Basiskardinalität beträgt immer 10'000 Zeilen!
Einige Anpassungen basieren auf Push-Path-Filtern

Mikael Eriksson
quelle