0

我有以下存储过程来遍历每天下载到服务器的数百个不同的 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
4

2 回答 2

0

看来您在循环中的 BULK INSERT 是瓶颈。通常,BULK INSERT 是检索数据的最快方式。无论如何,这里的文件数量似乎是你的问题。

为了让事情变得更快,您需要并行读取 JSON 文件。您可以通过首先为所有文件或某些文件组创建完整的动态 sql 查询并同时读取来做到这一点。

我宁愿建议使用带有脚本组件的集成服务作为并行数据流任务的源。首先从目标文件夹中读取所有文件,例如将它们分成 4 个组,因为每个组都有一个并行运行的循环容器。根据您的执行机器,您可以使用尽可能多的并行流。Allready 2 数据流应该弥补集成服务的开销。

另一种选择是编写CLR(公共语言运行时)存储过程并使用 C# 并行反序列化 JSON。

它还取决于执行这项工作的机器。你会想要有足够的随机存取内存和空闲的 cpu 能力,所以应该考虑在机器不忙的时候进行导入。

于 2016-05-20T08:52:24.500 回答
0

因此,当从大量单独的 XML 文件将数据加载到表中时,我成功的一种方法是使用 SQL Server 的 FileTable 功能,您可以将其应用于此问题。

它的工作方式是在数据库中设置一个文件表,然后允许访问在服务器上为上传 XML 文件的进程创建的 FileStream 共享。然后将 XML 文件放入共享中,并立即在数据库中使用 xPath 进行查询。

然后,一个进程将运行 xPath 查询,将 XML 中的所需数据加载到所需的表中,并跟踪已加载的文件,然后在下一个计划出现时,仅从最新文件加载数据。

然后,机器上的计划任务将在不再需要文件时将其删除。

在此处阅读 FileTable:

文件表 (SQL Server)

它适用于所有 SQL Server 版本。

于 2016-05-23T11:52:59.523 回答