我们正面临使用 Azure 逻辑应用服务和 SQL 数据库一起运行三个存储过程 (SP) 的问题。
无论 SP 的运行顺序如何,问题总是出现在第一个运行的 SP 中。
该处理最初需要几秒钟才能成功运行和执行,但我们注意到执行时间和所需的 DTU(数据库吞吐量单位)每天都在增加。
其中一个 SP 使用按日期过滤表格的变量TABLE1
,并仅在TABLE2
. 过滤器变量(在 SP 中使用)在逻辑应用程序中定义为SUBSTRING(startOfDay(utcNow()), 0, 10)
,它返回当前日期值。
我们的代码包括TABLE1
仅过滤当天的值,将其放入TABLE2
,对其运行一些计算并将结果存储回TABLE1
. SP 代码中使用了WITH
、Last_Value
和函数。该函数用于将结果行插入(约 74 行)。First_Value
INSERT
INSERT
TABLE1
记录的数据行TABLE1
数每天都在增加,但是TABLE2
由于是“当天”过滤的结果,所以数据行数是恒定的,所以它只显示当天的值。
使用 SQL Server Management Studio,可以毫无问题地手动执行 SP。
一开始,当我们的数据库 DTU 设置为 400 时,第一个 SP 的 Logic App 执行时间不到 10 分钟,而其余两个 SP 的执行时间分别为几秒钟。
最近第一个 SP 执行失败,出现 GatewayTimeout 错误,逻辑应用执行失败:
当我们将 DTU 增加到 800 时,逻辑应用程序成功运行,但我们仍然收到 GatewayTimeout 的警告。
检查了与数据库的连接,测试了每个单独的 SP 的手动执行,将过滤器变量数据类型从datetime
to更改为varchar
(与逻辑应用程序参数匹配),但问题不断出现。
如果不解决,这个问题有可能再次发生。有什么建议么?
谢谢。
更新
这是一个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