I have a database that keeps track of a hierarchical relationship between items. Each item has an ID field that is the primary key. Each item also has a parentID field that maps to the ID field of its parent.Currently, I am able to retrieve a set of items while also retrieving the number of children it has. I use a query similar to this:USE [MY_DATABASE]SELECT [ID], [Prop1], [Prop2] ,(SELECT COUNT(*) FROM [MyTable] AS [B] WITH (NOLOCK) WHERE [B].[ParentID] = [A].[ID] ) AS [Child_Count]FROM [MyTable] AS [A] WITH (NOLOCK)WHERE [A].[Prop1] = 'something'
This works great for small result sets, but is incredibly slow for larger ones. This is understandable, having a correlated subquery that does a full table scan.I actually don't need to know the number of children an item has. All I need to know is if it has children or not. True/false or 0/1 will do. I've tried a few different things but nothing performs as well as the above statement.Statements like this are worse performers:USE [MY_DATABASE]SELECT [ID], [Prop1], [Prop2] ,(CASE WHEN EXISTS (SELECT top 1 * FROM [MyTable] AS [B] WITH (NOLOCK) WHERE [B].[ParentID] = [A].[ID]) THEN 1 ELSE 0 END) AS [Child_Count]FROM [MyTable] AS [A] WITH (NOLOCK)WHERE [A].[Prop1] = 'something'
And this:USE [MY_DATABASE]SELECT [ID], [Prop1], [Prop2] ,(SELECT COUNT(*) FROM (SELECT TOP 1 * FROM [MyTable] AS [B] WITH (NOLOCK) WHERE [B].[ParentID] = [A].[ID] ) AS [dummy] ) AS [Child_Count]FROM [MyTable] AS [A] WITH (NOLOCK)WHERE [A].[Prop1] = 'something'
Both the previous statements are significantly slower than the original query. This is unintuitive for me. Can someone help me find a fast way to determine if an item has children or not?I'm using SQL Server 2005 Service Pack 2 (SP2) (v9.0.3042).