Мы столкнулись с проблемой одновременного запуска трех хранимых процедур (SP) с использованием службы Azure Logic Apps и баз данных SQL.
Независимо от последовательности выполнения SP, проблема всегда проявляется в первом запущенном SP.
Первоначально обработка и успешное выполнение занимали несколько секунд, но мы заметили, что время выполнения и требуемые DTU (единицы пропускной способности базы данных) увеличивались день ото дня.
Один из SP использует переменную, которая фильтрует таблицу TABLE1
по дате и показывает только данные «текущего дня» в TABLE2
. Переменная фильтра (используемая в SP) определена в приложении Logic как SUBSTRING(startOfDay(utcNow()), 0, 10)
, которая возвращает значение текущего дня.
Наш код состоит из фильтрации значений TABLE1
только для текущего дня, помещения его в TABLE2
, выполнения над ним некоторых вычислений и сохранения результатов обратно в TABLE1
. Функции WITH
, Last_Value
, First_Value
и INSERT
используются внутри кода SP. Функция INSERT
используется для вставки результирующих строк в TABLE1
(около 74 строк).
Количество строк данных, записанных в TABLE1
, увеличивается каждый день, но количество строк данных в TABLE2
постоянно, поскольку это результат фильтрации «текущего дня», поэтому он показывает только значения текущего дня.
Используя SQL Server Management Studio, SPs выполняются вручную без каких-либо проблем.
В начале, когда наша база данных DTU была установлена на 400, приложение логики для первого SP требовало менее 10 минут для выполнения, а остальные два SP занимали по несколько секунд каждый.
В последнее время не удается выполнить первый SP, выдает ошибку GatewayTimeout и выполнение приложений логики не удается:
Когда мы увеличили DTU до 800, приложения логики работают успешно, но мы по-прежнему получаем предупреждение о GatewayTimeout.
Соединение с базой данных было проверено, ручное выполнение каждого отдельного SP было проверено, изменение типа данных переменной фильтра с datetime
на varchar
(в соответствии с параметром Logic Apps) было выполнено, но проблема продолжает возникать.
Существует тенденция к тому, что эта проблема будет повторяться, если не будет решена. Какие-либо предложения?
Спасибо.
ОБНОВИТЬ
Это код одного SP:
WITH enTotTable
AS
(
SELECT --TOP(100)
se.id
, se.gatewayName
, se.deviceId
, se.ts
, se.pointNameId
, case
when se.presentValue < 0 then 0 else se.presentValue end as presentValue
, DATEPART(hh,se.ts) as hTs
FROM dbo.SolarEnergyTable se
WHERE se.gatewayName IN ('DPJW', 'DAN1') and se.pointNameId = 7 and not se.presentValue = 0 and se.ts >= @tsFilter
)
, calculationTable AS
(
SELECT distinct
FORMAT ( tot.ts , 'yyyy-MM-dd' ) as dayTs
,tot.deviceId
,tot.gatewayName
, CASE
WHEN Last_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
ORDER by tot.hTs ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FIRST_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
ORDER by tot.hTs ) >=12
then 1
Else NULL end as ifAllDay
, CASE
WHEN Last_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
ORDER by tot.hTs ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FIRST_VALUE(tot.hTs) OVER(partition by tot.deviceId, DATEPART(dd, tot.ts)
ORDER by tot.hTs ) >=12
then (LAST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
ORDER by tot.deviceId desc, tot.ts
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FIRST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
ORDER by tot.deviceId desc, tot.ts) )
else NULL
end as enTdy
,case
when LAST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
ORDER by tot.deviceId desc, tot.ts
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) < 0 then NULL
else
LAST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
ORDER by tot.deviceId desc, tot.ts
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
end as lastPvalueDay
, case
when FIRST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
ORDER by tot.deviceId desc, tot.ts
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) < 0 then NULL
else
FIRST_VALUE(tot.presentValue) OVER(partition by tot.deviceId, DAY(tot.ts)
ORDER by tot.deviceId desc, tot.ts)
end as firstPvalueDay
FROM enTotTable tot
WHERE not tot.presentValue = 0
)
, plantAndTdyTable
AS
(
SELECT
tdy.gatewayName
,tdy.dayTs as ts
,CAST(2 as INT) as deviceId
, CAST(20 as INT) as pointNameId
, Case When
tdy.ifAllDay = 1
then SUM(tdy.lastPvalueDay)-SUM(tdy.firstPvalueDay)
else NULL end as presentValue
FROM calculationTable tdy
GROUP BY tdy.dayTs ,tdy.ifAllDay, tdy.gatewayName
UNION
SELECT
tdy.gatewayName
,tdy.dayTs as ts
,CAST(2 as INT) as deviceId
, CAST(17 as INT) as pointNameId
,SUM(tdy.lastPvalueDay) as presentValue
FROM calculationTable tdy
GROUP BY tdy.dayTs, tdy.gatewayName
UNION
SELECT
tdy.gatewayName
, tdy.dayTs as ts
, tdy.deviceId
, CAST(6 as INT) as pointNameId
, tdy.enTDY as presentValue
From calculationTable tdy
)
INSERT INTO [dbo].[SolarEnergyTable]
SELECT
pt.gatewayName
,pt.ts
,pt.deviceId
,pt.pointNameId
,pt.presentValue
FROM plantAndTdyTable pt
-- SELECT *
-- From
-- plantAndTdyTable
-- -- calculationTable
-- -- enTotTable