根据 Conor 的建议,您可以调整您的触发器代码,将 JSON 分解为将 500 万行分解为临时表。使用 SELECT INTO 即时创建临时表 (#),并使用 IDENTITY 函数向临时表添加行标识符。如果您认为有必要,这将允许您将最终的 INSERT 批处理到主表中。
然后INSERT 来自临时表的记录现在是记录格式,而不是 JSON,直接进入您的主表。这应该只需要几秒钟,具体取决于正在运行的其他进程、数据库设置的层等。这样,您可以将 JSON 分解为两个不同的操作,从而减少每个操作的负载,并利用tempdb 用于临时存储。像这样的:
-- Take the historical JSON and shred it into a temp table as records
SELECT
IDENTITY( INT, 1, 1 ) AS rowId,
t.rowId originalRowId,
j.[key],
JSON_VALUE ( j.[value], '$.data1' ) AS [data1],
JSON_VALUE ( j.[value], '$.data2' ) AS [data2],
JSON_VALUE ( j.[value], '$.data3' ) AS [data3]
INTO #tmp
FROM yourLandingTable t
CROSS APPLY OPENJSON ( yourJSON ) j
-- Now insert the records into the main table in batches
INSERT INTO yourMainTable ( data1, data2, data3 )
SELECT data1, data2, data3
FROM #tmp
WHERE rowId Between 1 And 1000000
INSERT INTO yourMainTable ( data1, data2, data3 )
SELECT data1, data2, data3
FROM #tmp
WHERE rowId Between 1 And 2000000
etc ...
INSERT INTO yourMainTable ( data1, data2, data3 )
SELECT data1, data2, data3
FROM #tmp
WHERE rowId > 5000000