Вставка 0,1 миллиона записей в Azure SQL Server занимает много времени - PullRequest
0 голосов
/ 13 апреля 2019

Я пытаюсь обработать документ Excel с 2 листами. 1-й лист содержит метаданные, а 2-й лист - фактические данные.

1-й лист содержит 10 столбцов, а второй - не менее 50 столбцов и может варьироваться. Прежде чем помещать данные в базу данных SQL Server, мне нужно проверить каждую ячейку листа. Некоторые из них являются только проверкой типа данных для листа, а некоторые столбцы необходимо проверить по значениям базы данных и соответствующим образом создать объект ошибки в случае сбоя.

Кроме того, сначала должны быть обработаны данные листа заголовка, а затем фактические данные. Отображения для заголовка и таблицы данных хранятся в базе данных и проверяются. Поскольку в заголовке не будет более 1000 записей, я обрабатываю и помещаю данные заголовка в базу данных за один раз.

Я преобразую столбцы таблиц данных в один объект json для строки, а затем для каждых 5000 строк я вызываю хранимую процедуру для вставки этих записей в базу данных.

Весь этот процесс проверки, создания объектов ошибок и отправки данных для почти 0,1 миллиона записей занимает почти 20 минут.

Есть ли способ, которым я могу сделать это быстрее? В будущем мы можем получить более 1 миллиона записей на листе.

Поскольку в хранимых процедурах также задействовано много логики, опция SqlBulkCopy здесь также не подходит.

CREATE PROCEDURE [dbo].[sp_AddData] (
    @Table DataTable READONLY,
    @DocumentType NVARCHAR(20)
)
AS
BEGIN

    IF(@DocumentType = 'abcd')
    BEGIN

        INSERT INTO dbo.Table1 (
                DMDId,
                SN, 
                Name, 
                Date, 
                GP, 
                D, 
                NP, 
                Data,
                IsLatest
        )
        SELECT 
                DMD.Id,
                PDDT.SN, 
                PDDT.Name, 
                PDDT.Date, 
                PDDT.GP, 
                PDDT.D, 
                PDDT.NP, 
                PDDT.Data,
                1
        FROM @Table PDDT
            INNER JOIN dbo.Table2 DMD
                ON DMD.TY = PDDT.TY AND 
                   DMD.TP = PDDT.TP AND 
                   DMD.IsLatest = 1
            INNER JOIN dbo.Table3 P
                ON P.CPID = PDDT.CPID AND 
                   DMD.PID = P.Id

    END


END
GO



 CREATE TYPE [dbo].[DataTable] AS TABLE
(
    [Id]                    [INT]               NULL,
    [SN]                    [NVARCHAR](50)      NOT NULL,
    [Name]                  [NVARCHAR](50)      NOT NULL,
    [Date]                  [DATETIME]          NOT NULL,
    [GP]                    [NUMERIC](22,2)     NOT NULL,
    [D]                     [NUMERIC](22,2)     NOT NULL,
    [NP]                    [NUMERIC](22,2)     NOT NULL,
    [Data]                  [NVARCHAR](MAX)     NOT NULL,
    [TP]                    [INT]               NOT NULL,   
    [TY]                    [NVARCHAR](20)      NOT NULL,   
    [CPId]                  [NVARCHAR](30)      NOT NULL
)
GO
...