Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

ODP.NET パフォーマンスチューニング(2)
データの一括コピー・キャッシュ・大容量データ

Oracle Data Provider for .NET(ODP.NET)の活用 第2回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/10/09 14:00

 .NETアプリケーションからOracleへ接続する場合、Oracle Data Provider for .NET(ODP.NET)には、Oracleへのアクセスを高速化させるための様々な機能が実装されています。今回は、Oracleデータベースとの接続パフォーマンスを向上させる方法として、「データの一括コピー」「SQL実行結果のキャッシュ」「ラージ・オブジェクトへの高速アクセス」の3つを紹介します。

目次

はじめに

 .NETアプリケーションからOracleへ接続するための最善の方法は、Oracle社が提供している「Oracle Data Provider for .NET」(以下、ODP.NET)を使うことです。今回は、ODP.NETを利用してデータベースへのアクセスを高速化する手法を説明します。

対象読者

  • Visual Basic、もしくはC#を使ってプログラムを作ったことのある人。
  • Oracleデータベース対応アプリケーション開発に興味のある人。

必要な環境

  • Visual Studio 2003/2005/2008
  • ODP.NET 11.1.0.6.20 以上(注1)
  • Oracle Database 11g Release 1以上
注1)ODP.NETのインストール

 ODP.NETのインストーラは、Oracle Technology Network(以下、OTN)からダウンロードできます。

データベースへのアクセス速度を向上させる方法

 データベースへのアクセス速度を上げるには、さまざまな方法があります。前回の『ODP.NET パフォーマンスチューニング 第1回』では以下の3つの方法を説明しました。

  1. コネクションプーリングを利用する
  2. データベースとのラウンドトリップを少なくする
  3. SQLの解析を少なくする

 今回は、以下の3つの方法を利用して、Oracle データベースとの接続パフォーマンスを向上させる方法を説明します。

  1. データの一括コピー
  2. SQLの実行結果をキャッシュする
  3. ラージ・オブジェクトへの高速アクセス

データの一括コピー

 一括コピー機能は、Oracleデータベース以外のデータソースからOracleデータベース内の表に対してデータを高速に一括ロードします。例えば、ExcelファイルからOracleデータベースにデータを取り込む際は、通常ですとExcelファイルをDataTable、もしくはDataReaderで読み込み、行単位でOracleデータベースにInsertしていたかと思いますが、一括コピー機能を利用すれば、複数行を一回でOracleデータベースの表に取り込むことができます。

 ODP.NETでこの一括コピー機能を利用するために、「OracleBulkCopy」クラスが用意されています。OracleBulkCopyクラスのメソッドとプロパティとして以下が用意されています。

表1
設定項目 内容
BatchSize バッチとしてデータベースに送信される行数を指定します
BulkCopyOptions Oracleデータベースが一括コピー操作の実行に使用するOracleConnectionオブジェクトを指定します
BulkCopyTimeout 中断される前に一括コピー操作が完了するまでの秒数を指定します
ColumnMappings データ・ソースと保存先表間の列マッピングを指定します
Connection Oracleデータベースが一括コピー操作の実行に使用するOracleConnectionオブジェクトを指定します
DestinationTableName データがロードされるデータベース表を指定します
NotifyAfter 通知イベントが生成される前に処理された行数を定義します

 上記プロパティの太字の部分はOracleBulkCopyを実行する際に必要なプロパティとなりますので、必ず設定してください。「OracleBulkCopy」クラスの「WriteToServer」メソッドを実行すると、「DestinationTableName」プロパティで指定されたデータベース表にデータが格納されます。以下のサンプルコードでは、Excelに格納されたデータをOracle Databaseに一括コピー機能を利用して取り込んでいます。

OracleBulkCopyの利用例(VB.NET)
'// Excelデータの取得
Dim eConn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
  "Data Source=C:\\Temp\\SmplData.xls;Extended Properties=""Excel 8.0;HDR=YES;"";")
eConn.Open()
Dim cmdFrom As New OleDbCommand("Select EMPID,EMPNAME From [Sheet1$]")
cmdFrom.Connection = eConn
Dim rdrFrom As OleDbDataReader = cmdFrom.ExecuteReader

'// Oracle Databaseへの接続
Dim oConn As New OracleConnection("User Id=scott;Password=tiger;Data Source=orcl11g")
oConn.Open()

'// インスタンス生成時コンストラクタにConnectionを指定
Dim obCopy As New OracleBulkCopy(oConn)

'// データがロードされるデータベース表を指定
obCopy.DestinationTableName = "emp"

'// データ・ソースと保存先表間の列マッピングを指定
obCopy.ColumnMappings.Add("empid", "empno")
obCopy.ColumnMappings.Add("empname", "job")

'// BulkCopyの実行
obCopy.WriteToServer(rdrFrom)
OracleBulkCopyの利用例(C#)
// Excelデータの取得
OleDbConnection eConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + 
    "Data Source=C:\\Temp\\SmplData.xls;Extended Properties=\"Excel 8.0;HDR=YES;\";");
eConn.Open();
OleDbCommand cmdFrom = new OleDbCommand("Select EMPID,EMPNAME From [Sheet1$]");
cmdFrom.Connection = eConn;
OleDbDataReader rdrFrom = cmdFrom.ExecuteReader();

// Oracle Databaseへの接続
OracleConnection oConn = 
  new OracleConnection("User Id=scott;Password=tiger;Data Source=orcl11g");
oConn.Open();

// インスタンス生成時コンストラクタにConnectionを指定
OracleBulkCopy obcopy = new OracleBulkCopy(oConn);
// データがロードされるデータベース表を指定
obcopy.DestinationTableName = "emp";
// データ・ソースと保存先表間の列マッピングを指定
obcopy.ColumnMappings.Add("empid", "empno");
obcopy.ColumnMappings.Add("empname", "job");

// BulkCopyの実行
obcopy.WriteToServer(rdrFrom);

SQLの実行結果をキャッシュする

 SQLの実行結果をキャッシュしておくことで、繰り返し実行される問合わせのパフォーマンスを向上させることができます。この結果をキャッシュする機能はOracle Database 11gから追加された「リザルト・キャッシュ」です。この「リザルト・キャッシュ」を利用することにより、SQL検索結果のみキャッシュするので、従来のキャッシュに比べ、メモリの使用効率をあげ、レスポンスの高速化をはかることができます。以下の図は、従来のキャッシュと結果キャッシュの違いを表しています。

従来のキャッシュとリザルト・キャッシュの違い

 SQLの結果キャッシュによってキャッシュされた情報はSGA上(共有プール内の領域)に格納され、ユーザ間でその情報が共有されます。定型的なレポートのクエリーなど、大量データにアクセスするが結果として返す行が少量な場合に非常に有効な機能です。

「リザルトキャッシュ」の仕組み
画像

 リザルト・キャッシュに格納されたキャッシュの結果は以下の条件で無効化されます。

  • サーバとの通信時にキャッシュした結果セットが更新などによって無効となったことがサーバから通知された
  • CLIENT_RESULT_CACHE_LAGで指定された時間、サーバとの通信が発生しなかった

 リザルト・キャッシュの利点として、既存のアプリケーションを変更せずにこのキャッシュ機能を利用することができます。この機能の設定と有効化はOracle Databaseの「RESULT_CACHE_MODE」初期化パラメータを変更します。設定項目は以下です。

表2
設定項目 説明
MANUAL
(デフォルト)
ユーザが手動でリザルト・キャッシュを行う指定をした場合のみ、リザルト・ キャッシュの機能が使用される
FORCE 常にリザルト・キャッシュの機能が働く

 Oracle Databaseの設定は、以下のように初期化パラメータの変更SQLを実行します。

リザルト・キャッシュを有効化する
alter system set RESULT_CACHE_MODE = 'FORCE';

 もし、RESULT_CACHE_MODEの値が「MANUAL」となっていた場合は、SQLの中にヒント句を入れることにより、クライアント・リザルトキャッシュ機能を有効にすることが可能です。

クライアント・リザルトキャッシュ機能の有効化
select /*+ result_cache */ first_name, last_name from employees

  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2009/10/09 10:57 ご指摘の通り、ColumnMappings~DestinationTableNameになります。分かりやすいようにコードの説明箇所でコメントを付けました。

  • 2009/10/01 11:24 画像ファイルをアップしたのですが、プレビューでは表示されないのでしょうか?

  • 2009/10/01 10:16 現在、記事修正中です。

著者プロフィール

  • 日本オラクル 大田(オオタ ヒロシ)

    日本オラクル株式会社 Oracle Directテクニカルサービス部所属。開発者の視点から、Oracle Databaseの機能を最大限に活かすための手法を日々研究しながら、プリセールス活動やオンラインセミナー等による情報発信を行う。現在はWindows Server上でのOracle製品活用を推進...

バックナンバー

連載:Oracle Tips

もっと読む

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5