sql >> Database >  >> RDS >> Sqlserver

Vraag over SQL Server HiërarchieID depth-first performance

Het is niet helemaal duidelijk of je probeert te optimaliseren voor diepte-eerst of breedte-eerst zoeken; de vraag suggereert eerst de diepte, maar de opmerkingen aan het einde gaan over de breedte eerst.

Je hebt alle indexen die je nodig hebt voor depth-first (indexeer gewoon de hierarchyid kolom). Voor de breedte is het niet genoeg om alleen maar te maken het berekende level kolom, moet u deze ook indexeren:

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

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

(Houd er rekening mee dat u voor niet-geclusterde indexen hoogstwaarschijnlijk de INCLUDE nodig hebt - anders kan SQL Server in plaats daarvan een geclusterde indexscan uitvoeren.)

Als u nu alle voorouders probeert te vinden, van een knooppunt, wilt u een iets andere overstag gaan. U kunt deze zoekopdrachten razendsnel uitvoeren, want - en dit is het leuke van hierarchyid - elk knooppunt "bevat" al zijn voorouders.

Ik gebruik een CLR-functie om dit zo snel mogelijk te doen, maar je kunt het doen met een recursieve 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, om alle voorouders en afstammelingen te krijgen, gebruik het als volgt:

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

Probeer het uit - dit zou uw prestatieproblemen moeten oplossen.



  1. Oracle Enterprise Manager vacature is opgehangen

  2. Juiste query om het huidige aantal verbindingen in een PostgreSQL DB te krijgen

  3. SQL Server datum Formaat gebruiker afhankelijk?

  4. Hoe grotere gegevens in de Oracle-tabellen invoegen/bijwerken?