sgmunson - Friday, June 23, 2017 10:07 AM
Steve,
Try it with a bit more test data and see where the two Triangular Joins come into play. Here's the test harness. Turn on the Actual Execution Plan and look for the big arrows.
SET NOCOUNT ON;
IF OBJECT_ID(N'dbo.DailyVisits', N'U') IS NOT NULL
BEGIN
DROP TABLE dbo.DailyVisits;
END;
GO
CREATE TABLE dbo.DailyVisits (
dt date NOT NULL,
visitor varchar(10) NOT NULL,
CONSTRAINT PK_DailyVisits PRIMARY KEY(dt, visitor)
);
CREATE NONCLUSTERED INDEX IX_DailyVisits_visitor_dt ON dbo.DailyVisits
(
visitor ASC,
dt ASC
);
--===== 10,000 visitors over a 5 year period
INSERT INTO dbo.DailyVisits
(dt, visitor)
SELECT TOP (10000)
dt = DATEADD(dd,ABS(CHECKSUM(NEWID())%DATEDIFF(dd,'2011','2017')),'2011') --2017 is exclusive here
,visitor = RIGHT(NEWID(),7)
FROM sys.all_columns ac1
CROSS JOIN sys.all_columns ac2
;
For more information on the devastating effect that Triangular Joins can have even on such small row counts, please see the following article.
http://www.sqlservercentral.com/articles/T-SQL/61539/
Also, because you're using an rCTE that counts, you also have to add a MAXRECURSION option if you want to be able to process more than 100 days. I wouldn't use the rCTE for this. Please see the following article on why you should never use one to create a sequence/count.
http://www.sqlservercentral.com/articles/T-SQL/74118/
--Jeff Moden
Change is inevitable... Change for the better is not.