Quantcast
Channel: SQL Server Database Engine Forum
Viewing all articles
Browse latest Browse all 15872

looking for a technique to make date range joins perform better

$
0
0

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


Viewing all articles
Browse latest Browse all 15872

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>