Hi we run 2017 standard. I've come across this challenge in the past but never solicited help on the matter.
Often, I come across situations where individual records in table A match only a SINGLE record in table B based on
a datetime range in table B that covers a single datetime column from table A. And indices dont seem capable of making
the match as efficient as other business scenarios where a datetime range isnt involved.
What do i mean? Lets say table A is the incident table (see index also) shown in the code block and it has 30.5 million
records that are newer (start datetime) than 2 years ago. and about 27 million older than 2 years ago.
And table B is the job table (see index also, notice no physical pk defined) shown in the code block and it has 3.3 million
records of which about 1.7 million jobs get a match as explained below. I should mention that presently endtime is null on jobs that arent finished yet.
It would be great if the following query would run much faster than 8-10 minutes. I suspect if the match criteria
involved only 1 or 2 column equivalents, it would. But date ranges seem to perform poorly. I verified that the indexes
shown in the code block are being used in the execution plan. Now that I look at the NC on the jobs table, I have to admit that I don't know what we were thinking.
select count(*) from
(
SELECT
inc.pk,
inc.StartTime,
inc.EndTime,
inc.machine
FROM dbo.incidents inc (NOLOCK)
JOIN dbo.jobs job (NOLOCK) ON inc.machine = job.machine
AND inc.StartTime >= job.StartTime
AND (inc.StartTime < job.EndTime OR job.EndTime IS NULL)
AND job.building = inc.building
AND (job.EndTime >= DATEADD(MONTH, -24, GETDATE()) OR job.EndTime IS NULL)
WHERE
inc.StartTime >= DATEADD(MONTH,-24,GETDATE())
) x
USE [mydatabase] SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[incident]( [Id01] [int] NULL, [EndTime] [datetime] NULL, [Id02] [int] NULL, [machine] [int] NULL, [Id03] [int] NULL, [Id04] [int] NULL, [Id05] [int] NULL, [Id06] [int] NULL, [Id07] [int] NULL, [StartTime] [datetime] NULL, [pk] [int] NOT NULL, [Id08] [int] NULL, [building] [varchar](25) NOT NULL, CONSTRAINT [PK_incident] PRIMARY KEY CLUSTERED ( [pk] ASC, [building] 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 USE [mydatabase] GO CREATE NONCLUSTERED INDEX [IDX_Incident_NCI02] ON [dbo].[Incident] ( [StartTime] ASC ) INCLUDE ( [id01], [End_Time], [machine], [id02], [id03], [id04], [id05], [id06], [id07]) 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 USE [mydatabase] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[jobs]( [Id01] [int] NULL, [EndTime] [datetime] NULL, [Id02] [int] NULL, [machine] [int] NULL, [jobId] [int] NOT NULL,--<-------------------this and building are unique [StartTime] [datetime] NULL, [building] [varchar](25) NOT NULL, ) ON [PRIMARY] GO USE [mydatabase] GO SET ANSI_PADDING ON GO CREATE NONCLUSTERED INDEX [IDX_Jobs_NCI02] ON [dbo].[Jobs] ( [StartTime] ASC, [EndTime] ASC, [machine] ASC, [building] ASC ) INCLUDE ( [id02]) 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