Frage zur SQL Server HierarchyID-Tiefenleistung

8

Ich versuche hierarchyID in einer Tabelle (dbo. [Message]) zu implementieren, die ungefähr 50.000 Zeilen enthält (wird in Zukunft wesentlich wachsen). Es dauert jedoch 30-40 Sekunden, um etwa 25 Ergebnisse abzurufen.

Der Wurzelknoten ist ein Füller, um Eindeutigkeit bereitzustellen, daher ist jede nachfolgende Reihe ein Kind dieser Dummy-Reihe.

Ich muss die Tabellentiefe zuerst durchqueren und die hierarchyID-Spalte (dbo. [Message] .MessageID) den Clustering-Primärschlüssel erstellen, außerdem eine berechnete smallint (dbo. [Message] .Hierarchy) hinzufügen welche die Ebene des Knotens speichert.

Verwendung: Eine .Net-Anwendung durchläuft einen hierarchyID-Wert in der Datenbank und ich möchte in der Lage sein, alle (falls vorhanden) untergeordneten UND-Eltern dieses Knotens abzurufen (neben dem root, da es ein Füller ist).

Eine vereinfachte Version der Abfrage, die ich verwende:

%Vor%

Soweit ich weiß, sollte der Index automatisch ohne Hinweis erkannt werden.

Von der Suche in Foren habe ich Leute gesehen, die Indexhinweise verwenden, wenn sie mit Indexen mit der größten Breite umgehen, aber diese Anwendung nicht in der ersten Tiefe beobachtet haben. Wäre das ein relevanter Ansatz für mein Szenario?

Ich habe in den letzten Tagen versucht, eine Lösung für dieses Problem zu finden, aber ohne Erfolg. Ich wäre sehr dankbar für jede Hilfe, und da dies mein erster Beitrag ist, entschuldige ich mich im Voraus, wenn dies eine 'noobish' Frage wäre, habe ich die MS Dokumentation gelesen und unzählige Foren durchforstet, bin aber nicht auf eine kurze Beschreibung von das spezifische Problem.

    
ObjectiveCat 26.04.2010, 14:26
quelle

2 Antworten

2

Problemumgehung gefunden: Ссылка

Ich erinnere nur daran, dass ich mit einem heirarchyID gestartet habe, das von der Anwendung übergeben wurde, und mein Ziel ist, alle Verwandten dieses Wertes (sowohl Vorfahren als auch Nachkommen) abzurufen.

In meinem speziellen Beispiel musste ich vor der SELECT -Anweisung die folgenden Deklarationen hinzufügen:

%Vor%

Die WHERE -Klausel wurde geändert in:

%Vor%

Der Anstieg der Abfrage-Performance ist sehr signifikant:

Für jedes eingegebene Ergebnis beträgt die Suchzeit jetzt durchschnittlich 20 ms (von 120 bis 420).

Bei der Abfrage von 25 Werten dauerte es vorher 25 - 35 Sekunden, um alle zugehörigen Knoten zurückzugeben (in einigen Fällen hatte jeder Wert viele Verwandte, in einigen gab es keine). Es dauert jetzt nur noch 2 Sekunden.

Vielen Dank an alle, die auf dieser und anderen Seiten zu diesem Thema beigetragen haben.

    
ObjectiveCat 26.04.2010, 20:58
quelle
8

Es ist nicht ganz klar, ob Sie versuchen, die Suche nach der Tiefe oder Breite zu optimieren. Die Frage schlägt Tiefe zuerst, aber die Kommentare am Ende sind über Breite zuerst.

Sie haben alle Indizes, die Sie für die Tiefe zuerst benötigen (indexieren Sie einfach die Spalte hierarchyid ). Für die Breite reicht es nicht aus, die berechnete level -Spalte einfach zu erstellen , sondern auch zu indizieren:

%Vor%

(Beachten Sie, dass Sie für nicht gruppierte Indizes höchstwahrscheinlich INCLUDE benötigen - andernfalls kann SQL Server stattdessen einen Clustered-Index-Scan durchführen.)

Wenn Sie nun versuchen, alle Vorfahren eines Knotens zu finden, möchten Sie etwas anders aussehen. Sie können diese Suchanfragen blitzschnell durchführen, denn - und hier ist was an hierarchyid - jeder Knoten "enthält" bereits alle seine Vorfahren.

Ich verwende eine CLR-Funktion, um dies so schnell wie möglich zu machen, aber Sie können es mit einem rekursiven CTE tun:

%Vor%

Um nun alle Vorfahren und Nachkommen zu erhalten, benutze es wie folgt:

%Vor%

Probieren Sie es aus - das sollte Ihre Leistungsprobleme lösen.

    
Aaronaught 26.04.2010 14:57
quelle