SQL Server でデータのインポート / エクスポートをする際には BCP ユーティリティを使用することが多いかと思います。
この BCP ユーティリティですが、単一のインプットファイルの中の特定のデータ範囲だけをインポート / エクスポートをするための機能があります。
今回はこの機能について少し書いてみたいと思います。
なお、この方法は SQL Database Migration Wizard でも使用されている方法になるようです。
# 設定ファイルの ChunkSize という項目がインポートデータの始点と終点の範囲を決めるための設定となり、データファイル内の特定の範囲をインポートしてから、次のデータ範囲を処理するという流れになっているようです。
BCP ユーティリティには -F (First Row) と -L (Last Row) というデータをインポート / エクスポートする際にデータ範囲の始点と終点を設定するためのオプションがあります。
エクスポートする際に設定することでどこまでのデータ範囲をファイルに出力するか、インポートする際に設定することで、どこまでのデータ範囲をインポートするかということを設定することができるようになります。
設定しなかった場合はファイル内の全データを対象として処理を実行することになります。
# この方法で BCP を実行することが多いかと思いますが。
エクスポートするときには範囲を指定することは少ないかと思いますが、インポート時には範囲指定は状況によっては便利なことがあります。
データインポートをする際には並列インポート (並列ロード) を実行して効率よくデータのロードを行うことがあります。
特定の範囲で分割したファイルを SSIS を使用して並列ロードすることは多いかもしれないですね。
# TPC-H のデータなどはインポートファイルを分割して作成できるので、この方法でロードすることがあるかと思います。
BCP で -F / -L を使用すると単一のインプットファイルでこれと同じようなことをすることができます。
1,500,000 件のデータが格納されている Native 形式の BCP データを 3 分割でロードするときは以下のようなコマンドをコマンドプロンプトから実行すると実現できます。
bcp [TEST].[dbo].[customer] in "C:SQLAzureMWBCPDatadbo.customer.dat" -E -n -b 10000 -a 16384 -F 1 -L 500000 -S <サーバー名> -U <ユーザー名> -P <パスワード> & pause |
上記のコマンドはインポートデータの特定の範囲内をコミット単位を 10,000 としてロードするものになります。
コマンドプロンプトから実行する場合は START コマンドで実行すると平行でインポートを走らせることもできます。
並列ロードについては データ ローディング パフォーマンス ガイド を参考にするとよいかと思います。
# 並列ロード時に BULK INSERT でブロッキングが発生することがありますので、できればヒープの状態でインポートするのが望ましいかと。
データファイルのサイズが大きいと、-F / -L でデータの範囲を絞るのにも時間がかかりますので、可能であればインプット用のファイルを分割しておいたほうがよいかと思いますが、単一のファイルで特定の範囲に分けてデータをインポートしたい場合にはこの方法を覚えておくとよいかもしれませんね。