There's something I'm not sure how to tackle with in the query I have.
First, definitions:
Courier Services table. With one record.
CREATE TABLE [dbo].[CS](
[ServiceID] [int] IDENTITY(1,1) NOT NULL,
[CSID] [nvarchar](6) NULL,
[CSDescription] [varchar](50) NULL,
[OperatingDays] [int] NULL,
[DefaultService] [bit] NULL,
CONSTRAINT [CourierServices_PK] PRIMARY KEY CLUSTERED
(
[ServiceID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90
) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[CS] ON
INSERT [dbo].[CS] ([ServiceID], [CSID], [OperatingDays], [DefaultService])
VALUES (1, N'RM48', 2, 1)
SET IDENTITY_INSERT [dbo].[CS] OFF
SET ANSI_PADDING ON
GO
/****** Object: Index [ix_CourierServices] Script Date: 19/04/2017 14:27:03 ******/
CREATE NONCLUSTERED INDEX [ix_CourierServices] ON [dbo].[CS]
(
[CSID] ASC,
[DefaultService] ASC,
[OperatingDays] ASC
)
INCLUDE ( [CSDescription]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Calendar DB and table, code by Genius Jim Horn :
CREATE TABLE [dbo].[days](
[PKDate] [date] NOT NULL,
[calendar_year] [smallint] NULL,
[calendar_quarter] [tinyint] NULL,
[calendar_quarter_desc] [varchar](10) NULL,
[calendar_month] [tinyint] NULL,
[calendar_month_name_long] [varchar](30) NULL,
[calendar_month_name_short] [varchar](10) NULL,
[calendar_week_in_year] [tinyint] NULL,
[calendar_week_in_month] [tinyint] NULL,
[calendar_day_in_year] [smallint] NULL,
[calendar_day_in_week] [tinyint] NULL,
[calendar_day_in_month] [tinyint] NULL,
[dmy_name_long] [varchar](30) NULL,
[dmy_name_long_with_suffix] [varchar](30) NULL,
[day_name_long] [varchar](10) NULL,
[day_name_short] [varchar](10) NULL,
[continuous_year] [tinyint] NULL,
[continuous_quarter] [smallint] NULL,
[continuous_month] [smallint] NULL,
[continuous_week] [smallint] NULL,
[continuous_day] [int] NULL,
[description] [varchar](100) NULL,
[is_weekend] [tinyint] NULL,
[is_holiday] [tinyint] NULL,
[is_workday] [tinyint] NULL,
[is_event] [tinyint] NULL,
PRIMARY KEY CLUSTERED
(
[PKDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Index [ix_days] Script Date: 19/04/2017 14:38:47 ******/
CREATE NONCLUSTERED INDEX [ix_days] ON [dbo].[days]
(
[PKDate] ASC
)
INCLUDE ( [is_weekend],
[is_holiday],
[is_workday],
[is_event]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Now, I'm running a query which references both tables as per bit of code:
Select
OID
,case when
Cast(o.[CreationDate] as time) > '16:00:00'
then (select top 1 [PKDate] from [calendar].[dbo].days
where is_weekend <> 1 and is_holiday <>1 and
PKDate > cast(o.[CreationDate] as date)
order by PKDate asc)
else (select top 1 [PKDate] from [calendar].[dbo].days
where is_weekend <> 1 and is_holiday <>1 and
PKDate >= Cast(o.[CreationDate] as date)
order by PKDate asc)
end OperatingDate
,case when
Cast(o.[CreationDate] as time) > '16:00:00'
then (select top 1 [PKDate] from [calendar].[dbo].days
where is_weekend <> 1 and is_holiday <>1 and
PKDate > dateadd(day,isnull(
(select top 1 [operatingdays]
from [dbo].[CS]
where DefaultService = 1)
,2)+1,Cast(o.[CreationDate] as date))
order by PKDate asc)
else (select top 1 [PKDate] from [calendar].[dbo].days
where is_weekend <> 1 and is_holiday <>1 and
PKDate > dateadd(day,isnull(
(select top 1 [operatingdays]
from [dbo].[CS]
where DefaultService = 1)
,2), Cast(o.[CreationDate] as date))
order by PKDate asc)
end EstimatedDeliveryDate
,(select dateadd(day,3,o.[CreationDate])) DeliveryDate
From o
Now the question is, related to index scans and number of executions: why the 2 BILLION? Or 6 Billion? Output of the whole query is, admittedly, 1.7M rows but that doesn't explain the insane numbers shown in the query plan:
https://www.brentozar.com/pastetheplan/?id=H1iahxHAe
If I can hammer flat all those scans I can reduce the query time significantly, but first of all: how do I interpret those numbers to find a solution?
The days table contains 7.6 k rows (to cover years 2000-2020).