我创建了一个触发器,该触发器应该使用表中更新的外键来更新表(
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
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 瓶颈?