I'm trying to calculate the number of simultaneous calls at the time a particular call is made by looking at the datetime ranges. My query works, but takes ~10 minutes to perform for only 95,000 records, which is too long. Any ideas for optimization?
SELECT r.*,
rr.ChannelsActive 'ChannelsActive'
FROM #rg r
OUTER APPLY
(
SELECT SUM(1) AS ChannelsActive
FROM #rg r_inner
WHERE
(
r_inner.CallStart BETWEEN r.CallStart AND r.CallEnd
OR r_inner.CallEnd BETWEEN r.CallStart AND r.CallEnd
OR r.CallStart BETWEEN r_inner.CallStart AND r_inner.CallEnd
OR r.CallEnd BETWEEN r_inner.CallStart AND r_inner.CallEnd
)
) rr
Example Data
CREATE TABLE #rg
(
CallStart DATETIME,
CallEnd DATETIME
)
CREATE INDEX ix1
ON #rg(CallStart, CallEnd)
CREATE INDEX ix2
ON #rg(CallEnd, CallStart);
WITH T(N, R)
AS (SELECT TOP (95000) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS RN,
ABS(120 + 30 * SQRT(-2 * LOG(ABS(CAST(CAST(CRYPT_GEN_RANDOM(8) AS BIGINT) AS FLOAT) / 9223372036854775807))) * COS(2 * PI() * ABS(CAST(CAST(CRYPT_GEN_RANDOM(8) AS BIGINT) AS FLOAT) / 9223372036854775807)))
FROM sys.all_objects o1,
sys.all_objects o2)
INSERT INTO #rg
SELECT DATEADD(SECOND, N, GETDATE()),
DATEADD(SECOND, N + R, GETDATE())
FROM T