Вы можете попытаться разделить операции.Например:
DROP TABLE IF EXISTS #tblTrips;
DROP TABLE IF EXISTS #tblTripsAgg;
CREATE TABLE #tblTrips
(
[TripID] [int] NOT NULL
,[Record] INT
,[ActualDateTime] [datetime]
,PRIMARY KEY ([TripID])
);
CREATE TABLE #tblTripsAgg
(
[TripID] [int] NOT NULL PRIMARY KEY
,Trips INT
);
INSERT INTO #tblTrips ([TripID], [Record], [ActualDateTime])
SELECT TripID
,IIF(RecordStatusID = 1, 0, IIF(Passengers + Other < 8, 1, CEILING((Passengers + Other) / 7.0)))
,CAST(RDate AS SMALLDATETIME) + CAST(RTime AS SMALLDATETIME)
FROM tblTrips
INSERT INTO #tblTripsAgg
SELECT TS.[TripID]
,SUM(T.[Record])
FROM #tblTrips TS
LEFT JOIN #tblTrips T
ON T.[ActualDateTime] >= TS.[ActualDateTime]
AND T.[ActualDateTime] <= DATEADD(MINUTE, 35, TS.[ActualDateTime])
GROUP BY TS.[TripID]
SELECT A.[TripID]
,A.[RDate]
,A.[RTime]
,A.[Passengers]
,A.[Other]
,A.[RecordStatusID]
,IIF(A.RecordStatusID = 1, '', CONCAT(Trips, ' Trips')) AS Trips
FROM tblTrips A
INNER JOIN #tblTripsAgg DS
ON A.TripID = ds.TripID;
Почему?Во-первых, иногда сложные запросы не оптимизируются корректно механизмом SQL, а во-вторых, вы можете легко увидеть, какая часть процесса является самой медленной.
Например, в приведенном выше примере первая часть просто делаетдата и время в одной дате.Кроме того, мы рассчитываем некоторые дополнительные вещи там.Таким образом, если эта часть запроса занимает много времени, просто предварительно рассчитав ее - используя триггер, используя предварительно вычисленный столбец или когда приложение касается таблицы.
Затем во втором запросе мы вычисляемсумма за каждый trip id
.Если эта часть медленная, может быть, мы можем создать другой индекс для таблицы, включающий ActualDateTime
, или если всегда у текущего идентификатора поездки дата больше, чем у предыдущей, мы можем добавить TS.TripID > T.TripID
, чтобы дополнительно ограничить строки?
Как вы сказали в комментариях, обрабатывается 300 000 строк, но это действительно небольшой объем данных, поэтому его выполнение не должно занимать так много времени.Если вы можете оптимизировать запрос дальше, поделитесь дампом данных.
Вы можете создать представление индекса, чтобы автоматически рассчитывать результаты первого запроса, поэтому никаких дополнительных усилий не требуется.
DROP VIEW IF EXISTS dbo.vw_tblTrips;
GO
CREATE VIEW dbo.vw_tblTrips WITH SCHEMABINDING
AS
SELECT TripID AS [TripID]
,IIF(RecordStatusID = 1, 0, IIF(Passengers + Other < 8, 1, CEILING((Passengers + Other) / 7.0))) AS [Record]
,CAST(RDate AS SMALLDATETIME) + CAST(RTime AS SMALLDATETIME) AS [ActualDateTime]
FROM dbo.tblTrips;
GO
CREATE UNIQUE CLUSTERED INDEX INX_vw_tblTrips
ON dbo.vw_tblTrips ([ActualDateTime], [TripID]);
GO