sql >> Database teknologi >  >> RDS >> Sqlserver

Spørgsmål om SQL Server HierarchyID depth-first performance

Det er ikke helt klart, om du forsøger at optimere til dybde-først eller bredde-først søgning; spørgsmålet antyder dybde først, men kommentarerne til sidst handler om bredden først.

Du har alle de indekser, du har brug for til depth-first (bare indekser hierarchyid kolonne). For bredden først er det ikke nok bare at oprette det beregnede level kolonne, skal du også indeksere den:

ALTER TABLE Message
ADD [Level] AS MessageID.GetLevel()

CREATE INDEX IX_Message_BreadthFirst
ON Message (Level, MessageID)
INCLUDE (...)

(Bemærk, at for ikke-klyngede indekser vil du højst sandsynligt have brug for INCLUDE - Ellers kan SQL Server ty til at lave en klynget indeksscanning i stedet.)

Hvis du nu prøver at finde alle forfædre af en node, vil du tage en lidt anden vinkel. Du kan gøre disse søgninger lynhurtige, fordi - og her er det fede ved hierarchyid - hver node "indeholder" allerede alle sine forfædre.

Jeg bruger en CLR-funktion til at gøre dette så hurtigt som muligt, men du kan gøre det med en rekursiv CTE:

CREATE FUNCTION dbo.GetAncestors
(
    @h hierarchyid
)
RETURNS TABLE
AS RETURN
WITH Hierarchy_CTE AS
(
    SELECT @h AS id

    UNION ALL

    SELECT h.id.GetAncestor(1)
    FROM Hierarchy_CTE h
    WHERE h.id <> hierarchyid::GetRoot()
)
SELECT id FROM Hierarchy_CTE

Nu, for at få alle forfædre og efterkommere, brug det sådan her:

DECLARE @MessageID hierarchyID   /* passed in from application */

SELECT m.MessageID, m.MessageComment 
FROM Message as m
WHERE m.MessageId.IsDescendantOf(@MessageID) = 1
OR m.MessageId IN (SELECT id FROM dbo.GetAncestors(@MessageID.GetAncestor(1)))
ORDER BY m.MessageID

Prøv det - dette burde løse dine præstationsproblemer.



  1. Oracle Forms 6i går ned med 0xC0000005 ved start efter installation af patch 19

  2. Korrekt måde at bruge LIKE '%{$var}%' med forberedte udsagn? [mysqli]

  3. Ikke en gyldig måned i oracle, når add_months bruges

  4. MySQL:udfylde tomme felter med nuller ved brug af GROUP BY