我有以下存储过程来遍历每天下载到服务器的数百个不同的JSON文件。
问题是查询需要15分钟才能运行,我需要尽快为大量的JSON文件创建类似的东西,是否有人能够指出我在提高性能方面的正确方向查询?
DECLARE @json VARCHAR(MAX) = ''
DECLARE @Int INT = 1
DECLARE @Union INT = 0
DECLARE @sql NVARCHAR(max)
DECLARE @PageNo INT = 300
WHILE (@Int < @PageNo)
BEGIN
SET @sql = (
'SELECT
@cnt = value
FROM
OPENROWSET (BULK ''C:\JSON\tickets' + CONVERT(varchar(10), @Int) + '.json'', SINGLE_CLOB) as j
CROSS APPLY OPENJSON(BulkColumn)
WHERE
[key] = ''tickets''
')
EXECUTE sp_executesql @sql, N'@cnt nvarchar(max) OUTPUT', @cnt=@json OUTPUT
IF NOT EXISTS (SELECT * FROM OPENJSON(@json) WITH ([id] int) j JOIN tickets t on t.id = j.id)
BEGIN
INSERT INTO
tickets (id, Field1)
SELECT
*
FROM OPENJSON(@json)
WITH ([id] int, Field1 int)
END
END
答案 0 :(得分:0)
看起来循环中的BULK INSERT是瓶颈。通常,BULK INSERT是检索数据的最快方法。无论如何,这里似乎文件的数量是你的问题。
为了加快速度,您需要并行读取JSON文件。您可以首先为所有文件创建完整的动态SQL查询,也可以为某些文件组创建并同时读取。
我建议将Integration Services与脚本组件一起用作并行数据流任务中的源。首先从目标文件夹中读取所有文件,例如将它们拆分为4组,因为每个组都有一个并行运行的循环容器。根据您的执行机器,您可以使用尽可能多的并行流。 Allready 2数据流应该弥补集成服务的开销。
另一种选择是编写CLR (common language runtime) stored procedure并使用C#并行反序列化JSON。
这还取决于机器完成工作。您可能希望有足够的随机存取内存和免费的CPU功率,因此在机器不忙时应考虑进行导入。
答案 1 :(得分:0)
因此,在将数据从大量单个XML文件加载到表中时,我可以成功地使用SQL服务器的FileTable功能,这是一种成功的方法。
它的工作方式是在数据库中设置文件表,然后允许访问在服务器上为上载XML文件的进程创建的FileStream共享。然后将XML文件放入共享中,并立即在数据库中使用,以便使用xPath进行查询。
然后运行一个进程xPath查询会将所需的数据从XML加载到所需的表中,并跟踪已加载的文件,然后在下一个计划出现时,只加载来自最新文件的数据。
计算机上的计划任务将在不再需要时删除文件。
在这里阅读FileTable:
它可用于所有SQL Server版本。