I have 2 tables (heavily simplified here to show relevant columns):
CREATE TABLE tblCharge (ChargeID int NOT NULL, ParentChargeID int NULL, ChargeName varchar(200) NULL) CREATE TABLE tblChargeShare (ChargeShareID int NOT NULL, ChargeID int NOT NULL, TotalAmount money NOT NULL, TaxAmount money NULL, DiscountAmount money NULL, CustomerID int NOT NULL, ChargeShareStatusID int NOT NULL)
I have a very basic View to Join them:
CREATE VIEW vwBASEChargeShareRelation as Select c.ChargeID, ParentChargeID, s.CustomerID, s.TotalAmount, isnull(s.TaxAmount, 0) as TaxAmount, isnull(s.DiscountAmount, 0) as DiscountAmount from tblCharge c inner join tblChargeShare s on c.ChargeID = s.ChargeID Where s.ChargeShareStatusID < 3 GO
I then have a view containing a CTE to get the children of the Parent Charge:
ALTER VIEW [vwChargeShareSubCharges] AS WITH RCTE AS ( SELECT ParentChargeId, ChargeID, 1 AS Lvl, ISNULL(TotalAmount, 0) as TotalAmount, ISNULL(TaxAmount, 0) as TaxAmount, ISNULL(DiscountAmount, 0) as DiscountAmount, CustomerID, ChargeID as MasterChargeID FROM vwBASEChargeShareRelation Where ParentChargeID is NULL UNION ALL SELECT rh.ParentChargeID, rh.ChargeID, Lvl+1 AS Lvl, ISNULL(rh.TotalAmount, 0), ISNULL(rh.TaxAmount, 0), ISNULL(rh.DiscountAmount, 0) , rh.CustomerID , rc.MasterChargeID FROM vwBASEChargeShareRelation rh INNER JOIN RCTE rc ON rh.PArentChargeID = rc.ChargeID and rh.CustomerID = rc.CustomerID ) Select MasterChargeID as ChargeID, CustomerID, Sum(TotalAmount) as TotalCharged, Sum(TaxAmount) as TotalTax, Sum(DiscountAmount) as TotalDiscount from RCTE Group by MasterChargeID, CustomerID GO
So far so good, I can query this view and get the total cost for a line item including all children.
The problem occurs when I join this table. The query:
Select t.* from vwChargeShareSubCharges t inner join tblChargeShare s on t.CustomerID = s.CustomerID and t.MasterChargeID = s.ChargeID Where s.ChargeID = 1291094
Takes around 30 ms to return a result (tblCharge and Charge Share have around 3.5 million records).
But the query:
Select t.* from vwChargeShareSubCharges t inner join tblChargeShare s on t.CustomerID = s.CustomerID and t.MasterChargeID = s.ChargeID Where InvoiceID = 1045854
Takes around 2 minutes to return a result - even though the only charge with that InvoiceID is the same charge as the one used in the previous query.
The same thing occurs if I do the join in the same query that the CTE is defined in.
I ran the execution plan for each query. The first (fast) query looks like this:
The second(slow) query looks like this:
I am at a loss, and my skills at decoding execution plans to resolve this are lacking.
I have separate indexes on tblCharge.ChargeID, tblCharge.ParentChargeID, tblChargeShare.ChargeID, tblChargeShare.InvoiceID, tblChargeShare.ChargeShareStatusID
Any ideas? Tested on SQL 2008R2 and SQL 2012