JavaによるSQL Serverへの大規模データ挿入手法

JDBCバッチ処理を使用した大量データ挿入

大量のデータをSQL Serverに挿入する際には、JDBCのバッチ処理機能を活用することでパフォーマンスを向上させることが可能です。この手法では複数のINSERT文をまとめて送信することで、ネットワーク通信のオーバーヘッドを削減できます。


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class BulkDataInserter {
    public static void main(String[] args) {
        String dbUrl = "jdbc:sqlserver://localhost:1433;databaseName=TargetDB;user=admin;password=securePass";
        String insertQuery = "INSERT INTO ProductInventory (ProductName, StockCount) VALUES (?, ?)";
        
        try (Connection connection = DriverManager.getConnection(dbUrl);
             PreparedStatement statement = connection.prepareStatement(insertQuery)) {
            
            connection.setAutoCommit(false);
            
            for (int i = 1; i <= 5000; i++) {
                statement.setString(1, "Item_" + i);
                statement.setInt(2, i * 10);
                statement.addBatch();
                
                if (i % 500 == 0) {
                    statement.executeBatch();
                    connection.commit();
                    statement.clearBatch();
                }
            }
            
            int[] remainingResults = statement.executeBatch();
            connection.commit();
            System.out.println(remainingResults.length + " records successfully inserted");
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
    

テーブル値パラメータを使用する方法

SQL Serverのテーブル値パラメータ機能を使用すると、複数行のデータを1つのパラメータとしてストアドプロシージャに渡すことができます。この方法ではデータベース側に事前にテーブル型を定義する必要があります。

データベース側の準備


-- テーブル型の作成
CREATE TYPE InventoryTableType AS TABLE 
    (ProductName NVARCHAR(50), StockCount INT);
GO

-- ストアドプロシージャの作成
CREATE PROCEDURE InsertInventoryData
    @InventoryData InventoryTableType READONLY
AS
BEGIN
    INSERT INTO ProductInventory (ProductName, StockCount)
    SELECT ProductName, StockCount FROM @InventoryData;
END
    

Bulk Insertを使用した高速データロード

大量のデータを短時間でロードするには、SQL ServerのBulk Insert機能を使用するのが効果的です。この方法ではデータを一時ファイルにエクスポートしてから一括ロードします。


BULK INSERT ProductInventory
FROM 'C:\\data\\inventory.csv'
WITH (
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n',
    FIRSTROW = 2,
    ERRORFILE = 'C:\\data\\import_errors.txt',
    TABLOCK
);
    

Javaアプリケーションからこの機能を利用する場合は、データをCSV形式でファイルに出力した後、ストアドプロシージャ経由でBulk Insertを実行します。

タグ: SQL Server JDBC Java バッチ処理 テーブル値パラメータ

6月7日 23:12 投稿