我们大约每分钟收集一次关于三个不同服务器的数据,并将其存储在名为“DirectAccessStat”的 SQL Server Express 2019 表中。
我们需要每隔 15 分钟报告一次连接总数(跨三台服务器)。
我有一个有效的 SQL 查询,但速度很慢,需要有关如何改进查询或建议不同方法的提示。
数据格式:
Id Server Time Connections CPU Memory Health
------ --------- ----------------------- ------------ ---- ------- -------
20250 Server3 2020-03-23 16:43:31.000 495 14 43 OK
20249 Server2 2020-03-23 16:43:29.000 550 20 75 OK
20248 Server1 2020-03-23 16:43:27.000 509 10 76 OK
20247 Server3 2020-03-23 16:42:24.000 494 8 43 OK
20246 Server2 2020-03-23 16:42:22.000 569 14 75 OK
20245 Server1 2020-03-23 16:42:20.000 510 20 76 OK
20244 Server3 2020-03-23 16:41:18.000 492 7 43 OK
20243 Server2 2020-03-23 16:41:16.000 565 11 75 OK
20242 Server1 2020-03-23 16:41:13.000 517 6 76 OK
20241 Server3 2020-03-23 16:40:11.000 495 14 43 OK
20240 Server2 2020-03-23 16:40:09.000 566 8 75 OK
20239 Server1 2020-03-23 16:40:06.000 519 16 76 OK
20238 Server3 2020-03-23 16:39:04.000 505 16 43 OK
20237 Server2 2020-03-23 16:39:02.000 574 12 75 OK
20236 Server1 2020-03-23 16:38:59.000 522 7 76 OK
20235 Server3 2020-03-23 16:37:57.000 515 10 43 OK
20234 Server2 2020-03-23 16:37:55.000 590 15 75 OK
20233 Server1 2020-03-23 16:37:52.000 523 6 76 OK
20232 Server3 2020-03-23 16:36:50.000 522 9 43 OK
20231 Server2 2020-03-23 16:36:47.000 583 15 75 OK
20230 Server1 2020-03-23 16:36:45.000 538 11 76 OK
20229 Server3 2020-03-23 16:35:43.000 520 10 43 OK
20228 Server2 2020-03-23 16:35:41.000 585 11 75 OK
20227 Server1 2020-03-23 16:35:38.000 539 8 76 OK
20226 Server3 2020-03-23 16:34:36.000 531 8 43 OK
20225 Server2 2020-03-23 16:34:34.000 602 17 75 OK
20224 Server1 2020-03-23 16:34:31.000 547 9 76 OK
20223 Server3 2020-03-23 16:33:28.000 533 9 43 OK
20222 Server2 2020-03-23 16:33:26.000 591 15 75 OK
20221 Server1 2020-03-23 16:33:24.000 545 11 76 OK
期望的输出(TotalConnections 是给定 15 分钟间隔后所有服务器的第一行的总和):
Time TotalConnections
---------------- ----------------
23.03 16:30 1703
23.03 16:15 1868
23.03 16:00 2046
23.03 15:45 2189
23.03 15:30 2336
23.03 15:15 2454
23.03 15:00 2531
23.03 14:45 2555
23.03 14:30 2621
23.03 14:15 2643
...
有效的 SQL,但速度很慢(并且每次迭代都作为新的子查询运行,因此输出很笨重..):
-- Find last whole quarter
DECLARE @now DateTime = GetDate();
DECLARE @minute int = 0;
DECLARE @nowminute int = DATEPART(MINUTE, @now);
IF @nowminute > 45
SET @minute = 45;
ELSE
IF @nowminute > 30
SET @minute = 30;
ELSE
IF @nowminute > 15
SET @minute = 15;
-- Set start time to last whole quarter
DECLARE @lookTime DateTime = DATETIME2FROMPARTS(YEAR(@now), MONTH(@now), DAY(@now), DATEPART(HOUR, @now), @minute, 0, 0, 0);
-- Continue lookup until specified end datetime
DECLARE @endTime DateTime = DATEADD(WEEK, -1, @lookTime);
-- Output time parts
DECLARE @datepart varchar(10);
DECLARE @hourpart varchar(2);
DECLARE @minutepart varchar(2);
WHILE @lookTime > @endTime
BEGIN
-- Set output time parts
SET @datepart = CONVERT(varchar(5), @lookTime, 104);
SET @hourpart = RIGHT('0' + CAST(DATEPART(HOUR, @lookTime) as varchar(2)), 2);
SET @minutepart = RIGHT('0' + CAST(DATEPART(MINUTE, @lookTime) as varchar(2)), 2);
SELECT (@datepart+' '+@hourpart+':'+@minutepart) AS [Time], SUM(D.Connections) AS TotalConnections
FROM DirectAccessStat D
INNER JOIN (
-- Select minimum Id grouped by server, after selected looktime
SELECT MIN(Id) AS Id
FROM DirectAccessStat
WHERE [Time] > @lookTime and [Time] < DATEADD(MINUTE, 20, @lookTime)
GROUP BY [Server]
) AS I
ON D.Id = I.Id;
-- Subtract 15 minutes from looktime
SET @lookTime = DATEADD(MINUTE, -15, @lookTime);
END