この章では、データ・カートリッジの設計に関連する様々な考慮事項について説明します。
この章の内容は、次のとおりです。
PL/SQL、C/C++またはJavaのオブジェクト型のメソッドを実装できます。PL/SQLおよびJavaのメソッドは、サーバーのアドレス空間で実行されます。C/C++のメソッドは外部プロシージャとしてディスパッチされ、サーバーのアドレス空間の外部で実行されます。
最善の実装方法は、状況に応じて異なります。次に一部のガイドラインを示します。
通常、CまたはC++が関係するコールアウトは、処理が実際にCPUにバインドされる場合に最も高速です。ただし、コールアウトにはディスパッチのコストが伴い、C/C++での処理量が小さい場合にはそのコストが重要になることがあります。
PL/SQLは、計算集中型でないメソッドに最も有効です。通常、大きいコード本体がデータ・カートリッジの一部に使用するものとは異なる言語ですでに実装されている場合や、広範囲な計算を実行する必要がある場合は、PL/SQLよりも他の実装オプションの方が適切です。
Javaは、比較的オープンな実装オプションです。通常、Javaはインタプリタで変換されますが、高パフォーマンスのアプリケーションではメソッドのプリコンパイルやジャストインタイム・コンパイラからメリットを得ている場合があります。
実行者権限メカニズムを使用すると、ファンクションを実行者の権限で実行できます。そのため、カートリッジは専用スキーマ内で有効であり、カートリッジが常駐するスキーマ内のオブジェクトを操作するための権限がなくても他のスキーマで使用できます。
コールアウトとともにLOB
を使用する際の考慮事項は、次のとおりです。
コールアウトをLOB
型(BFILE
/BLOB
)に依存しないようにコーディングするとメリットがあります。
カートリッジのPL/SQLレイヤーでは、コールアウトでBFILE
固有のロジックが必要にならないようにBFILE
をオープンできます(BFILE
を操作しないOCILob
コールからのエラー・リカバリの場合以外)。
一時LOB
がある場合は、一時LOB
を使用して割当てとコールが行われるときに発生する可能性があるディープ・コピーに注意する必要があります。必要に応じてBLOB
パラメータにNOCOPY
(BY REFERENCE
)を使用してください。
従来、外部プロシージャにはステートレス・モデルがあります。外部プロシージャの起動時にオープンされた文ハンドルは、すべてコール終了時に暗黙的にクローズされます。
Oracle Databaseでは、データベース内のOCI文ハンドルおよび関連する状態などの状態情報を保存し、セッション中に外部プロシージャの複数の起動にまたがって使用できます。デフォルトでは、カートリッジはステートレスです。ただし、OCI_DURATION_SESSION
または他の適切な期間を指定してOCIMemory
サービスおよびOCIContext
サービスを使用すると、状態を保存できます。ある外部プロシージャの起動時に作成された文ハンドルは、別の起動時に再利用できます。データ・カートリッジ開発者は、これらのハンドルを明示的に解放する必要があります。明示的な解放は、文ハンドルが不要になった直後に実行することをお薦めします。その結果、OCIハンドルとデータベース内の文について維持されている状態がすべて解放されます。これにより、データ・カートリッジの拡張性が向上します。
関連項目 『Oracle Database PL/SQL言語リファレンス』 |
この項では、データ・カートリッジの索引を設計する際の考慮事項について説明します。
ドメイン索引を作成することが常に最善の方法であるとはかぎりません。ドメイン索引を作成することにした場合は、次の事項に注意してください。
複合ドメイン索引の場合、ファンクション実装は、データ・サイズが小さく、結果がデータ・サイズ全体の大部分を占める場合により適切に動作します。
拡張可能オプティマイザを適切に使用するとパフォーマンスを向上できます。
ドメイン索引実装の内部コンポーネントに対するネーミングが問題になる場合があります。内部データ・オブジェクトの名前は、通常、表および索引に指定する名前に基づきます。問題は、内部オブジェクトの導出名が他のユーザー定義オブジェクトやシステム・オブジェクトと競合しないようにする必要があることです。この問題を回避するには、名前を制限するなんらかのポリシーを開発するか、なんらかのメタデータ管理方法を実装して、DROP
やCREATE
などの実行中のエラーを回避します。
索引構成表に2次索引を作成できます。2次索引を使用する方が、特にデータのほとんどが索引にある場合に、表のデータと索引を個別に格納するよりも効率的であるためです。データに複数の方法でアクセスする場合、この方法には大きなメリットがあります。Oracle9iより前のリリースでは、索引構成表に作成できる索引が1つのみであることに注意してください。
索引構造をLOB
に格納できますが、最適なパフォーマンスが得られるようにLOB
を慎重にチューニングしてください。特定のLOB
に頻繁にアクセスする場合は、CACHE
オプションを指定して表を作成し、LOB
索引を個別の表領域に置きます。LOB
を頻繁に更新する場合は、TURN
OFF
LOGGING
を実行し、CHUNK
サイズの倍数単位で読み書きします。LOB
の特定部分に頻繁にアクセスする場合は、LOB
バッファリングまたは独自のバッファリング方法を使用して読取りまたは書込みをバッファに入れます。
拡張可能索引付けフレームワークでは、ユーザー定義索引の意味と表現をカートリッジ開発者が指定します。Oracleでは、索引構成表のように基本的な索引実装が提供されます。複合索引構造を格納するために、バイナリまたはキャラクタLOB
も使用できる場合があります。索引構成表、BLOB
およびCLOB
は、すべてデータベース内で有効です。さらに、ユーザー定義索引をBFILE
のようなデータベース外部の構造に格納することもできます。
外部索引構造を使用すると、索引を最も柔軟に表現できます。外部索引構造が特に役立つのは、すでにインメモリー索引付け構造の開発に着手している場合です。たとえば、オペレーティング・システム・ファイルに索引データを格納すると、実行時にメモリー・マップ・ファイルに読み取られます。このような場合は、外部索引ルーチンでBFILE
として処理されます。
外部索引構造は優れたパフォーマンスも提供できますが、これにはある程度のコストを伴います。データベース外部の索引構造がデータベースのトランザクション・セマンティクスに関与しない場合、データベース内の索引構造については、データと同時実行される索引更新をアトミックにします。これは、データの更新により拡張可能索引付けインタフェースを介して外部索引の更新が起動される場合に、失敗するとデータ更新はロールバックされますが、索引は更新されないことを意味します。データベースでロールバックできるのは、データベース内部のデータ更新のみで、外部索引構造をデータベース・ロールバックと同期的にロールバックすることはできません。外部索引構造は、読取り専用アクセスの場合に最も有効と思われます。データ更新が関与する場合は、そのセマンティクスが複雑になります。
ODCIIndexFetch()ルーチンがコールされると、演算子述語を満たす行すべてのROWIDが戻されます。ODCIIndexFetch()ルーチンで戻すことのできる最大行数はnrows
(nrows
はODCIIndexFetch()ルーチンの引数)です。nrows
の値は、なんらかの内部ファクタに基づいてOracleにより決定されます。最適な問合せパフォーマンスを達成するために戻す必要のある適切な行数がわかっている場合は、この行数がnrows
のかわりにODCIRidList
VARRAY
で戻されるように指定できます。ODCIRidList
の値の数がnrows
以下である必要があることに注意してください。
カートリッジ設計者は、戻される行数を判断できる最適のユーザーです。たとえば、索引の1500
のROWIDがまとめて格納されていて、nrowsが2000
の場合は、2000
行ではなく1500
行を戻すのが最適となります。それ以外の場合、ユーザーは3000
個のROWIDを取り出し、その中から2000
個を戻す必要があり、1000
個のROWIDが戻されないことになります。
特定の最適化を念頭においていない場合は、nrows
の値を使用して戻される行数を決定できます。現在、nrows
の値は2000
に設定されています。
コールアウトを使用する索引を実装する場合は、複数行フェッチを使用して最大行数をサーバーにフェッチします。これにより、コールアウトのコストが相殺されます。
オプティマイザが索引付けされた実装を使用しないように選択した場合は、すべてのドメイン索引に演算子の索引付き実装とファンクション実装の両方を含む必要があります。ただし、索引付け構造を使用するとファンクションの結果を生成できます。
データ・カートリッジは、拡張可能オプティマイザを考慮して設計する方が効率的になる場合があります。この項では、このような設計の作成に役立つトピックについて説明します。
一般的なプロファイラまたはツールを使用して、Cの関数の実行コストを判断できます。SQL問合せの場合は、問合せのEXPLAIN PLANにより問合せのコストの概算見積りが得られます。また、tkprof
ユーティリティを使用すると、操作に関連するCPUとI/Oのコスト情報を収集できます。さらに、SELECT FROM DUALのSQL問合せにコールアウトを使用し、tkprof
を使用してコストを見積もると、コールアウトの実行コストを判断できます。
述語の選択性とは、述語により戻される行数を表の合計行数で除算した値です。選択性は、表の行数に対する、述語により戻される行数の割合です。
選択性ファンクションでは、表について収集された統計を使用して、表の行数のうち引数リストを指定した述語で戻される行数のパーセンテージを判別する必要があります。たとえば、Image
SelectedImage
よりも大きいイメージを判別する述語IMAGE_GREATER_THAN
(Image
SelectedImage
)の場合は、データベース内のイメージのサイズのヒストグラムを使用して選択性を計算できます。
統計は、ドメイン索引のコストのみでなく述語の選択性の計算にも影響する場合があります。
表について収集された統計は、述語の選択性の計算に影響する場合があります。つまり、ユーザーは統計を参考にすることで、表および列について収集する必要のある述語の選択性をより適切に判断できます。データを操作できる述語がわかっていれば、収集する統計を決定する際に役立ちます。
たとえば空間ドメインの場合、VARRAY
内で空間オブジェクトのノードを含む要素の平均数、最小数および最大数は、収集すると役立つ統計です。
ドメイン索引の分析時には、ドメイン索引を構成する基礎となるオブジェクトの統計を分析する必要があります。たとえば、ドメイン索引が表で構成されている場合、ドメイン索引の分析時には統計収集ファンクションで表を分析する必要があります。ドメイン索引にアクセスするコストは、その索引について収集された統計の影響を受ける場合があります。たとえば、ドメイン索引にアクセスするコストは、ドメイン索引へのアクセス時にアクセスされる各種の表の合計データ・ブロック数を選択性で乗算した値として概算できます。
コスト、選択性および統計ファンクションを正確に定義するには、ドメインを十分に理解している必要があります。前述のガイドラインは、コスト、選択性および統計ファンクションの作業中における一部の考慮事項を理解するにあたって参考となることを意図したものです。通常は、デフォルトのコストおよび選択性を使用することから始めて、関心のある問合せの動作を観察することをお薦めします。
データ・カートリッジを設計する際の、メンテナンス関連の考慮事項は次のとおりです。
特にカートリッジで多数のオブジェクト、ビュー、表などをメンテナンスする場合には、ユーザーのためにオブジェクト間のリレーションシップを維持するためのメタデータ表を作成することを検討してください。これにより、カートリッジを開発して使用中にメンテナンスするという複雑さが軽減されます。
カートリッジにREADME
を添付して、ユーザーにインストール方法を指示します。
可能な場合は、sqlplus @imginst
のようにデータベースにカートリッジを一度にインストールできるようにします。
コールアウトを使用する場合は、ユーザーにlistener
の起動方法を指示します。
ユーザーにextproc
の設定方法を指示します。ほとんどのユーザーにはextproc
に関する知識がなく、多くのユーザーはリスナーを設定したことがありません。これは、カートリッジをデプロイする際に重要な問題になります。
Oracle Software Packagerを使用すると、instantiate_file
アクションを使用してカスタムのSQLインストール・スクリプトを容易に作成できます。この機能では、インストール時にファイル内の変数を置換し、インストール用にカスタマイズされたスクリプトとファイルをユーザーに提供できます。
関連項目 listener およびextproc の設定の詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。 |
データ・カートリッジの移植性を高めるための考慮事項は、次のとおりです。
oratypes.h
内のデータ型を使用します。
できるかぎりOCIコールを使用します。
できるかぎりANSI C準拠を規定するスイッチを使用します。
ANSI C関数プロトタイプを使用します。
できるかぎり開発サイクルの早期段階でターゲット・プラットフォーム上で作成し、テストします。これにより、プラットフォーム固有のコードを特定することが容易になり、再設計に最大限の時間をかけることができます。
移植性が低下する原因は、次のとおりです。
エンディアン(ビッグ/リトル)固有のデータの格納。
浮動小数点データ(IEEE/VAX/その他)の格納。
オペレーティング・システム固有のコール(使用する必要がある場合は、オペレーティング・システム固有のレイヤーに隔離します。ただし、必要なコールがOCIになく、POSIXにもない場合、困難な問題が生じる可能性があります)。
64ビット・プラットフォームにおけるint
のsize_t
としての暗黙的キャスト