“select * into”太慢

问题描述 投票:0回答:1

我在sql server中有一个存储过程:

CREATE OR ALTER PROCEDURE dbo.basic_json_normalization_full 
    @tableNamep sysname,
    @tableName sysname,
    @columns_list NVARCHAR(MAX),
    @json_query NVARCHAR(MAX),
    @rows_count INT OUTPUT AS BEGIN
    SET NOCOUNT, XACT_ABORT ON;
    
    DECLARE @main_tableName NVARCHAR(MAX) = 'dbo.' + @tableName;
    DECLARE @raw_tableName NVARCHAR(MAX) = 'dbo.' + 'raw' + @tableNamep;

    -- Truncate the main table  DECLARE @truncateQuery NVARCHAR(MAX);
    SET @truncateQuery = 'TRUNCATE TABLE dbo.' + @tableName;
    EXECUTE sp_executesql @truncateQuery;

    -- Construct the dynamic SQL
    DECLARE @sql NVARCHAR(MAX);

    SET @sql = N'
    BEGIN TRAN;
    INSERT INTO ' + @main_tableName + '
      (_id, ORIGINAL_ID, ' + @columns_list + ')
    SELECT j.[_id], j.[ORIGINAL_ID], ' + @columns_list + '
    FROM ' + @raw_tableName + ' r
    CROSS APPLY OPENJSON(r.raw_data)
      WITH ( _id nvarchar(155) ''$._id'', ORIGINAL_ID NVARCHAR(150) ''$.ORIGINAL_ID'', ' + @json_query + ') AS j;
    SET @rows_count = @@ROWCOUNT;
    COMMIT TRAN;
    ';

    -- Execute the dynamic SQL
    EXEC sp_executesql @sql, N'@rows_count int OUTPUT', @rows_count = @rows_count OUTPUT; END; GO

此过程在 Spring Batch Tasklet 中使用,更具体地说是在名为

JsonNormalize
的方法中使用:

@Override
    public int jsonNormalize(JdbcTemplate jdbcTemplate, String tableName, String chargement) {
              return simpleJdbcCall.withProcedureName("basic_json_normalization_full")
                    .withSchemaName("dbo")
                    .declareParameters(new SqlParameter("@tableName", Types.NVARCHAR))
                    .declareParameters(new SqlParameter("@tableNamep", Types.NVARCHAR))
                    .declareParameters(new SqlParameter("@columns_list", Types.NVARCHAR))
                    .declareParameters(new SqlParameter("@json_query", Types.NVARCHAR))
                    .execute(in);
}

这是 tasklet 片段代码:

@Bean
    public Step BasicNormalization(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
        return new StepBuilder(String.join("", BASIC_NORMALIZATION), jobRepository)
                .tasklet(basicNormalizationTasklet(), transactionManager)
                .throttleLimit(5)
                .build();
    }

有什么方法可以让这个更快一点,因为到目前为止,处理 120 万行需要 4 个小时。

PS:我尝试在 SQL Server Management Studio 中执行此操作,它也花费了太长的时间,因此有什么方法可以在 Spring Batch 中使用多线程或分区选项来使其更快。

sql-server stored-procedures spring-batch
1个回答
0
投票

多线程不会提高步骤的性能,甚至可能会产生不正确的结果,因为多个线程会在同一数据集上同时执行相同的过程。

您可以尝试对输入数据集进行分区并配置分区步骤,其中每个工作线程处理不同的分区(即每个线程将在不同的数据集上调用该过程)。

© www.soinside.com 2019 - 2024. All rights reserved.