Почему выполнение запроса как подзапрос медленнее, чем его выполнение последовательно такое же количество раз?
select top 1 login from SiemensLicUsage
where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-1,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
Запрос выполняется быстро.
Но если выполнить его как подзапрос для каждой даты из заданного диапазона дат:
DECLARE @StartDate DATE = DATEADD(DAY,-10,CONVERT(DATE,GETDATE()))
, @EndDate DATE = CONVERT(DATE,GETDATE())
select dt,
(
select top 1 login from SiemensLicUsage where SiemensLicUsage.licId='cam_base' and
SiemensLicUsage.filename='109012981' and CONVERT(DATE,SiemensLicUsage.logDateTime)=CONVERT(DATE, dt)
) LicUsageCount
from
-- Генерация диапазона дат между заданными значениями------------------
(
SELECT DATEADD(DAY, nbr - 1, @StartDate) dt
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS nbr
FROM sys.columns c
) nbrs
WHERE nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)
) dates
------------------------------------------------------------------------
order by dt desc;
Выполняется 5 секунд, хотя в диапазоне всего 11 дат.
Пробую этот подзапрос выполнить последовательно для тех же 11 дат:
spoiler
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=CONVERT(DATE, GETDATE())
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-1,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-2,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-3,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-4,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-5,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-6,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-7,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-8,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-9,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
select top 1 login from SiemensLicUsage where CONVERT(DATE,SiemensLicUsage.logDateTime)=DATEADD(DAY,-10,CONVERT(DATE, GETDATE()))
and SiemensLicUsage.licId='cam_base' and SiemensLicUsage.filename='109012981';
Выполняется 2 с копейками секунды.
Массив дат в будущем может быть очень большим.
Генерация массива дат без подзапроса выполняется также быстро.
Генерацию массива дат пробовал выносить в CTE и во временную таблицу, результат тот же.
Версия SQL Server 2008 R2.