Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7697581
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T22:03:01+00:00 2026-05-31T22:03:01+00:00

I have a simple temp-table defined in SQL Server 2008 R2 representing a parent-child

  • 0

I have a simple temp-table defined in SQL Server 2008 R2 representing a parent-child relationship. There can be multiple levels of hierarchy (say, up to 10). I’m using a CTE to find children in my table that are at least level 3 in the descendency hierarchy – in other words have at least a parent AND a grandparent.

Here is a script to demonstrate the set up and the CTE I am using:

set nocount on
create table #linkage(entity_key bigint, parent_key bigint)
--alter table #linkage add foreign key (parent_key) references #linkage(entity_key)

insert into #linkage values(1, 1), (2, 2), (3, 3), (4, 1), (5, 4), (6, 5)
print 'all data:' select * from #linkage

print 'level 3+ descendents:' 
;with r(entity_key, parent_key, level) as
(
    select entity_key, parent_key, 1
        from #linkage
        where entity_key = parent_key
    union all
    select p.entity_key, r.parent_key, r.level + 1
        from #linkage p
        inner join r on p.parent_key = r.entity_key 
        where p.entity_key <> r.entity_key
)
select entity_key, parent_key as ultimate_parent_key
from r
where r.level > 2

The correctly outputs the following:

all data:
entity_key           parent_key
-------------------- --------------------
1                    1
2                    2
3                    3
4                    1
5                    4
6                    5

level 3+ descendents:
entity_key           ultimate_parent_key  level
-------------------- -------------------- -----------
5                    1                    3
6                    1                    4

The problem is that I need this to work with large data sets. When I run this against 12 million rows, it takes over 3 minutes to complete, which I’m hoping to significantly reduce.

I have tried creating various combinations of clustered and non-clustered indexes (entity_key), (entity_key, parent_key), etc. but nothing seems to help (indeed, some seem to slow it down).

Here is the execution plan against the 12 million rows with no indexes:

  |--Filter(WHERE:([Recr1014]>(2)))
       |--Index Spool(WITH STACK)
            |--Concatenation
                 |--Compute Scalar(DEFINE:([Expr1015]=(0)))
                 |    |--Compute Scalar(DEFINE:([Expr1004]=(1)))
                 |         |--Table Scan(OBJECT:([tempdb].[dbo].[#linkage]), WHERE:([tempdb].[dbo].[#linkage].[entity_key]=[tempdb].[dbo].[#linkage].[parent_key]))
                 |--Assert(WHERE:(CASE WHEN [Expr1017]>(100) THEN (0) ELSE NULL END))
                      |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1017], [Recr1008], [Recr1009], [Recr1010]))
                           |--Compute Scalar(DEFINE:([Expr1017]=[Expr1016]+(1)))
                           |    |--Table Spool(WITH STACK)
                           |--Compute Scalar(DEFINE:([Expr1011]=[Recr1010]+(1)))
                                |--Filter(WHERE:([tempdb].[dbo].[#linkage].[entity_key] as [p].[entity_key]<>[Recr1008]))
                                     |--Index Spool(SEEK:([p].[parent_key]=[Recr1008]))
                                          |--Table Scan(OBJECT:([tempdb].[dbo].[#linkage] AS [p]))

Here is the same plan in XML format in case you’re into that kind of thing:

http://pastebin.com/Kx559C10

I should also note that this box has 12 CPUs, so if there is some way we can introduce some parallelism then this may help.

Can anyone recommend a method to speed this up?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T22:03:02+00:00Added an answer on May 31, 2026 at 10:03 pm

    Have you tried an index on parent_key and adding entity_key as an included column?

    Marking root nodes with NULL parents, rather than pointing back to themselves, ought to help:

    declare @linkage table (entity_key bigint, parent_key bigint null) 
    
    insert into @linkage values
      (1, NULL), (2, NULL), (3, NULL), (4, 1), (5, 4), (6, 5), (7, 3), (8, 7), (9, 5) 
    
    ;with r(entity_key, immediate_parent, root, level) as 
    (
      -- Faster search for NULL to find roots.
      select entity_key, entity_key as immediate_parent, entity_key as root, 1 
        from @linkage 
        where parent_key is NULL
      union all
      -- No WHERE clause needed.
      select p.entity_key, r.entity_key, r.root, r.level + 1 
        from r inner join
          @linkage as p on p.parent_key = r.entity_key  
    ) 
    select *
      from r
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

We have the following simple Stored Procedure that runs as an overnight SQL server
I'm trying to run a query in SQL Server 2008 against a table where
Thanks in advance! I have a Function in SQL server 2008 which splits a
I'm using embedded SQL with Java. I have a simple table where I want
I have simple SSIS package where I import data from flat file into SQL
I am using IDS 10 and I have a simple transaction table with the
Let's say i have a simple table voting with columns id(primaryKey),token(int),candidate(int),rank(int). I want to
My SQL is rusty -- I have a simple requirement to calculate the sum
In a SQL Server 2008R2 sproc, I have the following code to calculate the
I have a simple query for update table (30 columns and about 150 000

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.