Reputation: 3718
I am trying to solve a performance issue on an inherited system that appears when we have a significant amount of data.
We have a table that contains the two fields "ItemID" and "ParentItemID". The "ParentItemID" field relates to another row in the same talbe where the "ItemID" field matches this row's "ParentItemID" field.
This relationship can be many, many rows deep in places.
The following query is being run and looks like it could be another cause of slowdown:
WHILE 1=1
BEGIN
SELECT @ParentID = ParentItemID FROM Items WHERE ItemID = @LastParentID
IF @parentID IS NULL
BEGIN
break
END
ELSE
BEGIN
SET @LastParentID = @ParentID
END
END
Is there a better way of doing this sort of recursive search?
note: we are NOT allowed to make table changes at this point, so adding a "RootItemID" column is not possible (I've already asked, as this would solve the problem outright!)
Upvotes: 0
Views: 46
Reputation: 3202
you can do it by a Common Table Expression
like :
;WITH cte_hierarchy
AS (SELECT *
FROM item
WHERE ItemID = @ParentID
UNION ALL
SELECT i.*
FROM item i
JOIN cte_hierarchy h
ON i.ItemID = h.ParentItemID)
SELECT *
FROM cte_hierarchy
WHERE .....
Upvotes: 1
Reputation: 33867
You could use a common table expression for this:
WITH Antecedents (ITemID, ParentItemID, Level)
AS
(
-- Anchor member definition
SELECT ItemID, ParentItemID, 0 AS Level FROM Items WHERE ItemID = @StartingID
UNION ALL
SELECT ItemID, ParentItemID, Antecedents.Level + 1 AS Level
FROM Items
INNER JOIN Antecedents
ON Antecedents.ParentItemID = Items.ItemID
)
SELECT TOP 1 @LastParentID = ItemID
FROM Antecedents
ORDER BY Level DESC
More info on recursive CTE's here:
http://msdn.microsoft.com/en-us/library/ms186243.aspx
Upvotes: 3