Tsql Azure SQL触发器处理500万行

Tsql Azure SQL触发器处理500万行,tsql,triggers,azure-sql-database,Tsql,Triggers,Azure Sql Database,我将遥测数据发送到一个由不同列组成的SQL表,其中一列接收一个实际上是json数组的varchar,例如: '[{"data1": 5,"data2": 12, "data3": 2},{"data1": 7,"data2": 8, "data3": 1},{"data1": 4,"data2": 2, "data3"

我将遥测数据发送到一个由不同列组成的SQL表,其中一列接收一个实际上是json数组的varchar,例如:

'[{"data1": 5,"data2": 12, "data3": 2},{"data1": 7,"data2": 8, "data3": 1},{"data1": 4,"data2": 2, "data3": 11}]'
此数组的长度可以更改,但数组的每个元素都由所有三个键/值组成

我想将这些数据集成到一个专用表中,该表的列为: 着陆表ID,数据1,数据2,数据3

我已经在我的落地台的每一个插件上开发了一个触发器来执行这个操作,它工作得很好。然而,我正在寻找最好的解决方案来集成我的登录表中已有的500万行。 在这里最好的方式是什么


当我使用Azure SQL时,我不能使用SQL代理,但我可以使用Azure函数。

我可能会将此设计为将Data Lake作为数据的登录区域,然后使用Azure函数进行一些处理,例如将JSON转换为表格格式,然后将最终加载到SQL表中

您可以与数据工厂协调


触发器上的数据卷可能会遇到性能问题。

我可能会将此设计为将data Lake作为数据的登录区,然后使用Azure函数进行一些处理,例如将JSON转换为表格格式,然后将最终加载到SQL表中

您可以与数据工厂协调


触发器上的那些数据卷可能会遇到性能问题。

您可以使用OPENJSON打开JSON数组并将其转换为行。此文档页面中有一个示例显示了您可以使用的模式:


您可以使用OPENJSON打开JSON数组并将其转换为行。此文档页面中有一个示例显示了您可以使用的模式:


根据Conor的建议,您可以修改用于分解JSON的触发器代码,将500万行分解为临时表。使用SELECT INTO动态创建临时表,并使用IDENTITY函数向临时表添加行标识符。如果您认为有必要,这将允许您将最终插入批处理到主表中

然后将临时表中的记录直接插入主表中,这些记录现在是记录格式,而不是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

根据Conor的建议,您可以修改用于分解JSON的触发器代码,将500万行分解为临时表。使用SELECT INTO动态创建临时表,并使用IDENTITY函数向临时表添加行标识符。如果您认为有必要,这将允许您将最终插入批处理到主表中

然后将临时表中的记录直接插入主表中,这些记录现在是记录格式,而不是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

是的,我很清楚SQL的处理方式,问题更多的是如何处理500万历史记录行,对应于大约2个月的时间,对日常摄入的影响最小。是的,我很清楚SQL的处理方式,问题更多的是如何处理500万历史记录行,这相当于大约2个月,对日常摄入的影响最小