超过 6200 行时,Azure SQL 触发器需要花费 36 倍的时间

问题描述 投票:0回答:1

我创建了一个触发器,该触发器应该使用表中更新的外键来更新表(

clients_kv
)。为了避免更新
regions_kv
中的所有值,我对
regions_kv
inserted
进行了一些额外的联接。
存储过程

regions_kv

仅选择

CleanupOldRecords
中每个标识符的最新值。我的问题是,当插入最多 6200 行时,触发器工作正常(大约 30 秒),但当达到 6300 行时,它会运行 18 分钟。
更新部分在触发器之外工作正常。如果我删除更新语句中的 

regions_kv

部分,它也可以工作。如果我删除

CASE WHEN
上的额外连接,它也会起作用。我已将 Azure 中的 DTU 加倍,没有任何差异。如果我分两批运行它(即为每个批次启动触发器),第一批大小为 3000,第二批大小为 3600,它总共运行大约 30 秒。我还没有创建任何索引。
在 Azure 中查看查询性能见解时,更新步骤持续时间比整个查询的 18 分钟短了几秒。 CPU 或 DATA IO 永远不会分别超过 30% 和 2%。

最重要的是理解为什么持续时间会呈指数增长。

非常感谢任何帮助或指出正确的方向!

inserted

	
sql-server triggers azure-sql-database
1个回答
0
投票

CREATE TRIGGER trg_instead_of_insert_regions_kv ON dbo.regions_kv -- instead of insert lets the user define how data is inserted INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON; -- Create a temporary table to hold distinct newValue_id values CREATE TABLE #AffectedValueIds ( newValue_id INT ); -- Insert distinct newValue_id values from the `inserted` rows into the temporary table INSERT INTO #AffectedValueIds (newValue_id) SELECT DISTINCT newValue_id FROM inserted; -- Insert the new rows into the target table INSERT INTO dbo.regions_kv SELECT * FROM inserted; -- Call the stored procedure to perform cleanup, referencing #AffectedValueIds EXEC dbo.CleanupOldRecords @SchemaName = 'dbo', @TableName = 'regions_kv'; -- Insert the new rows into the target table and create a new forreign key UPDATE cl SET fk_regional_council_id = CASE WHEN r1.newValue_type = 'REGION_TYPE_REGIONAL_COUNCIL' THEN r1.newValue_id WHEN r2.newValue_type = 'REGION_TYPE_REGIONAL_COUNCIL' THEN r2.newValue_id WHEN r3.newValue_type = 'REGION_TYPE_REGIONAL_COUNCIL' THEN r3.newValue_id ELSE NULL END, fk_region_id = COALESCE(r1.newValue_id, r2.newValue_id, r3.newValue_id) FROM dbo.clients_kv as cl INNER JOIN inserted as i ON cl.newValue_operationalRegionIds = i.newValue_id -- we only want the cleaned observations from inserted INNER JOIN regions_kv r0 ON r0.header_eventId = i.header_eventId INNER JOIN regions_kv r1 ON r1.newValue_id = cl.newValue_operationalRegionIds LEFT JOIN regions_kv r2 ON r2.newValue_id = r1.newValue_parentRegionId LEFT JOIN regions_kv r3 ON r3.newValue_id = r2.newValue_parentRegionId SET NOCOUNT OFF; END;

此外,请确保连接中使用的列和 CASE 表达式已正确索引。

您查看过 Azure SQL 数据库查询性能洞察吗?此 T-SQL 代码是否被确定为最大的 CPU 或 IO 瓶颈?

© www.soinside.com 2019 - 2024. All rights reserved.