यह पूरी तरह से स्पष्ट नहीं है कि आप गहराई-प्रथम या चौड़ाई-प्रथम खोज के लिए अनुकूलित करने का प्रयास कर रहे हैं; प्रश्न गहराई-पहले का सुझाव देता है, लेकिन अंत में टिप्पणियाँ चौड़ाई-पहले के बारे में हैं।
आपके पास पहले गहराई के लिए आवश्यक सभी अनुक्रमणिकाएं हैं (बस hierarchyid
को अनुक्रमित करें कॉलम)। चौड़ाई-प्रथम के लिए, केवल बनाने . के लिए पर्याप्त नहीं है परिकलित level
कॉलम, आपको इसे भी अनुक्रमित करना होगा:
ALTER TABLE Message
ADD [Level] AS MessageID.GetLevel()
CREATE INDEX IX_Message_BreadthFirst
ON Message (Level, MessageID)
INCLUDE (...)
(ध्यान दें कि गैर-संकुल अनुक्रमणिका के लिए आपको INCLUDE
की सबसे अधिक आवश्यकता होगी - अन्यथा, SQL सर्वर इसके बजाय एक संकुल अनुक्रमणिका स्कैन करने का सहारा ले सकता है।)
अब, यदि आप सभी पूर्वजों को खोजने का प्रयास कर रहे हैं एक नोड के लिए, आप थोड़ा अलग सौदा करना चाहते हैं। आप इन खोजों को बहुत तेज़ बना सकते हैं, क्योंकि - और यहाँ hierarchyid
के बारे में बढ़िया बात है - प्रत्येक नोड में पहले से ही उसके सभी पूर्वज "शामिल" हैं।
मैं इसे जितनी जल्दी हो सके बनाने के लिए एक सीएलआर फ़ंक्शन का उपयोग करता हूं, लेकिन आप इसे एक पुनरावर्ती सीटीई के साथ कर सकते हैं:
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
अब, सभी पूर्वजों और वंशजों को प्राप्त करने के लिए, इसका उपयोग इस प्रकार करें:
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
इसे आज़माएं - इससे आपकी प्रदर्शन समस्याओं का समाधान हो जाना चाहिए।