「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>データアクセスのいろいろ]] * 目次 [#o4d63a30] #contents *基本情報 [#jddec5c0] **[[ADO.NETデータプロバイダ]] [#c9a8762b] ADO.NETのデータプロバイダを使用する.NETプログラムでは、~ 大量データを処理するバッチ開発に適合しないケースがある。 ***機能 [#i08d009b] -ADO.NETのデータプロバイダでは以下の機能がサポートされていないケースがある。~ #JDBCなどのデータプロバイダには標準で実装されている機能~ --フェッチ・サイズ指定(フェッチ) --配列バインド(バッチ更新) -Oracle、HiRDBのデータプロバイダについてはサポートされているものもある。 --ODP.NET ---フェッチ・サイズ指定(フェッチ) ---配列バインド(バッチ更新) --HiRDB.NET ---配列バインド(バッチ更新) ***SQLを連続して記述 [#c4464186] DBによるが、INSERT、UPDATEなどのSQLを連続して記述することは可能。 -以下は、SQL Serverの例 INSERT INTO XXXX(xxx, yyy, zzz) VALUES(xxx, yyy, zzz); INSERT INTO XXXX(xxx, yyy, zzz) VALUES(xxx, yyy, zzz); INSERT INTO XXXX(xxx, yyy, zzz) VALUES(xxx, yyy, zzz); ・・・ UPDATE SET xxx=xxx, yyy=yyy, zzz=zzz, WHERE id = 1; UPDATE SET xxx=xxx, yyy=yyy, zzz=zzz, WHERE id = 2; UPDATE SET xxx=xxx, yyy=yyy, zzz=zzz, WHERE id = 3; ・・・ -ただし、バインド変数の数に制約があるため、~ パラメタライズド・クエリでの「パラメタ」を設定し難い。 **SQL CLR [#s09edf33] ***概要 [#v2c03541] -SQL Server 2005からサポートされた機能。 -.NETではSQL CLRと言う機構も用意されているが、 --インプロセスで動作するものの --カーソル操作をサポートしない >ため、バッチ処理の用途では、あまり魅力的なものでは無い。 -また、同様にサポートされているデータプロバイダが限られる。 --SQL Server(SQL CLR) --ODP.NET(.NETストアド・プロシージャ) ***[[参考>#n8f7b6db]] [#pfc772f0] **SQL Server2008 [#oe67f8d1] ***INSERT ステートメントで複数の行の値を指定 [#o8771315] -INSERTで複数の値を指定することが可能となった(UPDATEは非対応)。 -同様に、バインド変数の数に制約があるため、~ パラメタライズド・クエリでの「パラメタ」を設定し難い。 -参考 --INSERT ステートメントで複数の値を指定 - 松本崇博 Blog (SQL Server Tips)~ http://d.hatena.ne.jp/matu_tak/20100113/1263856222 ***テーブル値パラメタ [#c5411901] -SQL Server 2008から、テーブル値パラメタというパラメタを設定可能になっている。 -テーブル値パラメタは、以下の型として、プログラム側から指定できる。 --.NET ---DataTable ---DbDataReader ---IEnumerable<T> --[[SQL CLR>#s09edf33]] ---SqlDataRecord -参考 --SQL Server 2008 のテーブル値パラメータ (ADO.NET)~ http://msdn.microsoft.com/ja-jp/library/bb675163.aspx --SQL ServerにおけるTable-Valuedパラメータ~ http://www.infoq.com/jp/news/2008/08/table-valued-param --Microsoft Docs ---テーブル値パラメーター~ https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/sql/table-valued-parameters ---テーブル値パラメーターの使用 (データベース エンジン)~ https://docs.microsoft.com/ja-jp/sql/relational-databases/tables/use-table-valued-parameters-database-engine --テーブル値パラメータについて少し整理とメモ - きよくらの備忘録~ http://kiyokura.hateblo.jp/entry/2015/04/04/111657 *検証 [#l6f776bc] 「フェッチ機能の代替」処理方式の検証 **処理方式 [#ze0c62fb] -SQL Serverのデータプロバイダを使用。 -フェッチ機能の代替 --フェッチ機能を代替するために、はじめに主キー・セットだけを取得し、~ コミット・インターバル分、IN句に主キーを指定して結果セットを分割取得~ することでフェッチ機能の代替とする方式もある。 --ただし、この際の検索処理性能を考慮すると、~ 参照元テーブルにインデックスが貼られている必要があるなど、~ 本処理方式(疑似フェッチ方式)を採用する上での制約もある。 **検証結果 [#w30f26a3] -100万件のデータのSELECT → INSERT処理を上記の疑似フェッチ方式で記述した場合、~ Transact-SQLでは15分程度であった処理が、.NETでもほぼ≒の時間で処理が完了した。 -まずまずの性能であり、''この方式が採用できる条件下''であれば~ 処理データ量が中規模のバッチであっても.NETで実装可能と考える。 **検証環境 [#ja1d310c] -また上記は、.NETのバッチプログラムをネットワーク上ではなく、~ DBサーバ上に直接配置した場合の性能情報である。 -ネットワーク経由の場合は、特に更新ラウンド・トリップのため低速になり、~ ネットワークの使用状況によっては非常に低速になる事もあるため注意が必要である。 *結論 [#je449a41] ***.NET+データプロバイダ [#s4216cb0] .NETプログラムでも、大量データを処理可能~ (ただし、ネットワーク経由はオーバーヘッドが大きいので注意)。 ***SQL CLR [#i0935aff] [[SQL CLR>#s09edf33]]の採用も考えられるが、採用例が少ないので、 -基本的には、 --SQL ServerであればTransact-SQL --OracleであればPL/SQL >が良いと考える(処理方式統一の標準化の意味も含めて)。 -文字列処理等にアドバンテージがあると言われているが、~ カーソル操作をサポートしていない点が大きな欠点となっている。 *参考情報 [#vdf1a7e1] **[[ストアド プロシージャ]] [#re9e9930] ***[[DBMS ネイティブなストアド プロシージャ>ストアド プロシージャ]] [#ode9faf4] ***[[CLR ストアド プロシージャ>ストアド プロシージャ]] [#n8f7b6db] **他言語との比較 [#x2a130cf] ***実績の多い言語 [#q9e6ae53] -COBOL(昔から使われており実績が多い) -各種ストアド(速度重視、大量データ) ***Javaとの比較 [#ob089083] Javaや.NETでの実績は上記に比べると多くは無いと思いますが、~ 最近は、Spring BatchなどのBatch Frameworkの登場で、~ Javaでもバッチが書かれることが増えてきてています。~ -Java --多重化 ---基本マルチスレッド化で多重化。 ---メモリ使用量(制限)の関係で、マルチスレッド化ではなく~ プロセスの多重起動で対応することもあるようです。 --Batch Framework~ ただ、Batch Frameworkが、少々オーバースペックの様で~ これをを理解して使いこなすのが難しいらしいです。 -.NET --多重化 ---マルチスレッド化、EXE多重起動の、両方が可能です。 ---.NETだと、EXE多重起動の方が一般的だと思います。~ マルチスレッド化が必要となるケースは、あまり思いつきません。 ---- Tags: [[:データアクセス]], [[:ADO.NET]], [[:Entity Framework]], [[:性能]]