Оптимизация запросов Microsoft Sql Server - присоединяйтесь по датам - PullRequest
0 голосов
/ 21 февраля 2019

как я могу улучшить производительность этого запроса?У меня должен быть 5-минутный раздел, и я хотел бы запустить его более чем на один день, в идеале на пять.Я не могу запустить как хранимую процедуру.

DECLARE @StartDate datetime = '2019-02-11 00:00:00.001'
       ,@EndDate   datetime = '2019-02-13 23:59:59.999';

WITH theDates AS
 (SELECT @StartDate as theDate
  UNION ALL
   SELECT DATEADD(MINUTE, 5, theDate)
    FROM theDates
   WHERE DATEADD(MINUTE, 5, theDate) <= @EndDate) 

SELECT theDate as Time,
(SELECT ISNULL(AVG(CONVERT(BIGINT, (CAST(DATEDIFF(ms, a.stmpmsg, b.stmpmsg) as decimal(38,2))))),0) as avg
FROM db1 as a INNER JOIN db2 as b
    ON a.ProcInstLUID = b.ProcInstLUID

    and a.integrationId LIKE 'TAG%' and a.integrationid = b.integrationid and a.stepid = 'TAG_1'

    and (b.stepid = 'TAG_2' and b.msgstatusdet like 'TAG_3%') 
    and a.serviceId = 'TAG_4' and b.serviceId = 'TAG_5'
    and a.stmpmsg > @StartDate
    and a.stmpmsg < @EndDate
    and a.stmpmsg < b.stmpmsg
    AND DATEPART(DAY, a.stmpmsg) = datepart(DAY,theDate)
    AND DATEPART(hh, a.stmpmsg) = datepart(hh,theDate) 
    AND (DATEPART(n, a.stmpmsg) >= datepart(n,theDate)
    and DATEPART(n, b.stmpmsg) < (datepart(n,theDate)+5))
    WHERE 1=1 
) AS AvgLng 
FROM theDates 
OPTION (MAXRECURSION 0)

Работает на Microsoft Sql Server, в прошлый раз для получения результата понадобилось около 17 часов.

1 Ответ

0 голосов
/ 21 февраля 2019

У нас здесь нет примеров данных, и я не совсем понимаю логику ОП.Это вместо этого, чтобы заставить мяч катиться за них.Без ответа я могу сделать немного больше:

DECLARE @StartDate datetime = '2019-02-11T00:00:00.001',
        @EndDate datetime = '2019-02-13T23:59:59.999';
--Let's use a tally to start with
WITH N AS (
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) V(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1 AS I
    FROM N N1 --10
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
         CROSS JOIN N N4 --10000 --That should be more than enough
    ),
--Generate the dates. Notice I provide both a start and end value
Dates AS(
    SELECT DATEADD(MINUTE, 5*T.I, @StartDate) AS StartDate,
           DATEADD(MINUTE, 5*(T.I+1), @StartDate) AS EndDate
    FROM Tally T
    WHERE DATEADD(MINUTE, 5*(T.I+1), @StartDate) <= @EndDate)
--And now, IF I understand your query correctly
SELECT {Columns go here}
FROM Dates D
     LEFT JOIN db1 a --A is a poor coice for an alias
          --This syntax is a little foreign to some, but I think it might be what you need
                   JOIN db2 b ON a.ProcInstLUID = b.ProcInstLUID
                              AND a.integrationId LIKE 'TAG%'
                              AND a.integrationid = b.integrationid
                              AND a.stepid = 'TAG_1'
                              AND (b.stepid = 'TAG_2'
                               AND b.msgstatusdet LIKE 'TAG_3%')
                              AND a.serviceId = 'TAG_4'
                              AND b.serviceId = 'TAG_5'
                   --This is pure guess work
                   ON a.stmpmsg >= D.StartDate
                  AND a.stmpmsg < D.EndDate
                  AND b.stmpmsg >= D.StartDate
                  AND b.stmpmsg < D.EndDate;;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...