ヘッダーをスキップ

Oracle Database 管理者ガイド
11gリリース1(11.1)

E05760-03
目次
目次
索引
索引

戻る 次へ

31 分散データベース・システムのアプリケーション開発

この章の内容は次のとおりです。

アプリケーション・データの分散の管理

分散データベース環境では、データベース管理者(DBA)と共同でデータの最適な格納場所を決めます。その際、次の点について考慮します。

データベース・リンクにより確立される接続の制御

SQL文やリモート・プロシージャ・コールの中でグローバル・オブジェクト名が参照されると、ローカル・ユーザーにかわってデータベース・リンクがリモート・データベース内のセッションへの接続を確立します。リモートの接続とセッションは、それまでにローカルのユーザー・セッションに対して接続が確立されていない場合にのみ作成されます。

リモート・データベースとの間に確立された接続とセッションは、アプリケーションやユーザーによって明示的に終了されないかぎり、ローカル・ユーザーのセッションの間存続します。データベース・リンクを経由してSELECT文を発行すると、UNDOセグメントにトランザクション・ロックが設定されます。セグメントを再び解放するには、COMMIT文またはROLLBACK文を発行する必要があります。

アプリケーションで不要になった高コストの接続を切断するには、データベース・リンクを使用して確立されたリモート接続を終了することが有効です。リモートの接続とセッションを終了するには、CLOSE DATABASE LINK句を指定したALTER SESSION文を使用します。たとえば、次のトランザクションを発行した場合を考えます。

SELECT * FROM emp@sales;
COMMIT;

次の文は、salesデータベース・リンクが指すリモート・データベース内のセッションを終了します。

ALTER SESSION CLOSE DATABASE LINK sales;

ユーザー・セッションのデータベース・リンク接続をクローズするには、ALTER SESSIONシステム権限が必要です。


注意:

データベース・リンクをクローズする前に、まずそのリンクを使用しているカーソルをすべてクローズし、次にそのリンクを使用している現行トランザクションがあればそのトランザクションを終了してください。 


関連項目:

ALTER SESSION文の詳細は、『Oracle Database SQLリファレンス』を参照してください。 

分散システムの参照整合性の維持

たとえば、整合性制約違反など、分散型の文の一部が失敗した場合、データベースはエラー番号ORA-02055を返します。以降の文またはプロシージャ・コールは、ROLLBACKまたはROLLBACK TO SAVEPOINTが発行されるまで、エラー番号ORA-02067を返します。

返されたエラー・メッセージをすべてチェックするようにアプリケーションを設計し、分散更新の一部が失敗したことを示すエラー・メッセージがないかを確認します。失敗を検出した場合は、トランザクション全体をロールバックしてからアプリケーションの処理を進めるようにしてください。

データベースでは、宣言参照整合性の制約を分散システムのノード間で定義することは許可されていません。つまり、1つの表での宣言参照整合性の制約では、リモート表の主キーまたは一意キーを参照する外部キーを指定することはできません。ただし、トリガーを使用してノード間の親子の表関係を維持することは可能です。

トリガーを使用して分散データベースのノード間で参照整合性を定義する場合は、ネットワークの障害によって親表だけでなく子表へのアクセスも制限される可能性があります。たとえば、子表がsalesデータベースにあり、親表がhqデータベースにあるとします。2つのデータベース間のネットワーク接続が失敗した場合、子表に対する一部のデータ操作言語(DML)文(子表に行を挿入する文や子表内の外部キーの値を更新する文など)が実行を継続できない場合があります。これは、参照整合性トリガーがhqデータベース内の親表にアクセスする必要があるためです。

関連項目:

トリガーを使用した参照整合性の規定の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 

分散問合せのチューニング

ローカルのOracle Databaseサーバーは、分散問合せを対応する数のリモート問合せに分割し、次に、その問合せを実行するためにリモート・ノードに送信します。リモート・ノードは問合せを実行し、その結果をローカル・ノードに返します。次に、ローカル・ノードは必要な後処理を実行し、その結果をユーザーまたはアプリケーションに返します。

問合せの処理が最適化されるようにアプリケーションを設計するには、いくつかの方法があります。この項の内容は、次のとおりです。

連結インライン・ビューの使用

分散問合せを最適化する最も効果的な方法は、リモート・データベースへのアクセスをできるだけ抑えて必要なデータのみを取得することです。

たとえば、分散問合せで5つのリモート表を2つの異なるリモート・データベースから参照し、複合フィルタ(WHERE r1.salary + r2.salary > 50000など)を使用するとします。この場合、リモート・データベースへのアクセスを1回にし、フィルタをリモート・サイトで適用するように問合せをリライトすることで、問合せのパフォーマンスを改善できます。このリライトにより、問合せを実行するサイトに転送されるデータの量が少なくなります。

リモート・データベースへのアクセスが1回になるように問合せをリライトするには、連結インライン・ビューを使用します。用語の定義は次のとおりです。

連結インライン・ビューを使用して分散問合せを構成し、分散問合せのパフォーマンスを改善することをお薦めします。Oracle Databaseのコストベース最適化を使用すると、分散問合せの多くが透過的にリライトされ、連結インライン・ビューによるパフォーマンスの向上が得られます。

コストベース最適化の使用

連結インライン・ビューによるクエリー・リライトに加えて、コストベース最適化の方法を使用すると、参照先の表から収集される統計とオプティマイザが実行する計算に従って分散問合せが最適化されます。

たとえば、コストベースの最適化によって次の問合せを分析します。この例では、表統計が使用できると仮定しています。CREATE TABLE文内の問合せが分析されます。

CREATE TABLE AS (
                 SELECT l.a, l.b, r1.c, r1.d, r1.e, r2.b, r2.c
                 FROM local l, remote1 r1, remote2 r2 
                    WHERE l.c = r.c 
                    AND r1.c = r2.c 
                    AND r.e > 300
                );

この文は、次のようにリライトされます。

CREATE TABLE AS (
                 SELECT l.a, l.b, v.c, v.d, v.e
                 FROM (
                        SELECT r1.c, r1.d, r1.e, r2.b, r2.c
                         FROM remote1 r1, remote2 r2
                         WHERE r1.c = r2.c 
                         AND r1.e > 300
                      ) v, local l
                 WHERE l.c = r1.c
                );

このリライトにより、別名vがインライン・ビューに割り当てられます。このインライン・ビューは、前述のSELECT文内の表として参照できます。連結インライン・ビューを作成することで、リモート・サイトで実行される問合せの量が減り、それによって高コストのネットワーク通信量が減少します。

コストベース最適化の動作の仕組み

オプティマイザの主なタスクは、連結インライン・ビューを使用するように分散問合せをリライトすることです。この最適化は、次の3つの手順で実行されます。

  1. マージ可能なビューがすべてマージされます。

  2. オプティマイザが連結問合せブロックのテストを実行します。

  3. オプティマイザが連結インライン・ビューを使用して問合せをリライトします。

問合せがリライトされた後、その問合せが実行され、データ・セットがユーザーに返されます。

コストベース最適化をユーザーに対して透過的に実行する場合は、複数の分散問合せのパフォーマンスを改善することはできません。特に、次のものが分散問合せに含まれている場合、コストベース最適化は効果がありません。

これらの要素が1つでも分散問合せに含まれている場合は、問合せの修正方法と、分散問合せのパフォーマンスを改善するためのヒントの使用について、「ヒントの使用」を参照してください。

コストベース最適化の設定

分散問合せのパフォーマンス改善のためにコストベース最適化を使用するようにシステムを設定すると、その処理がユーザーに対して透過的になります。つまり、問合せの発行時に自動的に最適化が実行されます。

コストベースの最適化を利用するようにシステムを設定するには、次のタスクを完了する必要があります。

環境の設定

コストベース最適化を使用可能にするには、OPTIMIZER_MODE初期化パラメータをCHOOSEまたはCOSTに設定します。このパラメータは次の方法で設定できます。

OPTIMIZER_MODE初期化パラメータをセッション・レベルで設定するには、次のどちらかの文を発行します。

ALTER SESSION OPTIMIZER_MODE = CHOOSE;
ALTER SESSION OPTIMIZER_MODE = COST;

関連項目:

パラメータ・ファイルのOPTIMIZER_MODE初期化パラメータの設定と、コストベース最適化方法を使用するためのシステムの構成の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。 

表の分析

コストベース最適化で分散問合せのための最も効率的なパスが選択されるようにするには、問合せに関係する表の正確な統計を提供する必要があります。そのためには、DBMS_STATSパッケージまたはANALYZE文を使用します。


注意:

DBMS_STATSプロシージャまたはANALYZE文を実行するには、表に対してローカルに接続する必要があります。たとえば、次の文は実行できません。

ANALYZE TABLE remote@remote.com COMPUTE STATISTICS; 

このANALYZE文または等価のDBMS_STATS プロシージャを実行するには、先にリモート・サイトへの接続が必要になります。 


次のDBMS_STATSプロシージャを使用すると、特定のクラスのオプティマイザ統計を収集できます。

たとえば、分散トランザクションが日常的にscott.dept表にアクセスするとします。コストベースのオプティマイザが引き続き最適な方法を確実に選択するように、次の文を実行します。

BEGIN
   DBMS_STATS.GATHER_TABLE_STATS ('scott', 'dept');
END;

関連項目:

  • 統計生成の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。

  • DBMS_STATSパッケージの使用の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

 

ヒントの使用

文が十分に最適化されない場合は、ヒントを使用してコストベース最適化の機能を拡張できます。特に、独自の問合せを記述して連結インライン・ビューを利用する場合は、分散問合せがリライトされないようにコストベース・オプティマイザに指示を与えます。

また、データベース環境に関する特別な情報(統計、負荷、ネットワークおよびCPUの制限事項、分散問合せなど)を持っている場合は、ヒントを指定してコストベース最適化を適切に誘導できます。たとえば、データベース環境の情報に基づく連結インライン・ビューを使用して、独自に最適化した問合せを記述した場合は、NO_MERGEヒントを指定することにより、オプティマイザが問合せをリライトしないようにできます。

この手法は、分散問合せに集計、副問合せまたは複合SQLが含まれている場合に特に役立ちます。このタイプの分散問合せはオプティマイザによってリライトできないため、NO_MERGEを指定して、オプティマイザが「コストベース最適化の動作の仕組み」で説明されている手順を省略するように指示します。

DRIVING_SITEヒントを使用すると、リモート・サイトを問合せ実行サイトとして機能するように定義できます。この方法では、問合せがリモート・サイトで実行され、データがローカル・サイトに返されます。リモート・サイトにデータの大部分が格納されているときは、このヒントが特に役立ちます。

関連項目:

ヒントの使用の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。 

NO_MERGEヒントの使用

NO_MERGEヒントは、データベースでインライン・ビューと連結されない可能性のあるSQL文とがマージされないようにするために使用します(「ヒントの使用」を参照)。このヒントは、SELECT文に埋め込みます。インライン・ビューを使用するSELECT文の先頭に引数として指定するか、またはインライン・ビューを定義する問合せブロック内に指定します。

/* with argument */

SELECT /*+NO_MERGE(v)*/ t1.x, v.avg_y
   FROM t1, (SELECT x, AVG(y) AS avg_y FROM t2 GROUP BY x) v,
   WHERE t1.x = v.x AND t1.y = 1;

/* in query block */

SELECT t1.x, v.avg_y
   FROM t1, (SELECT /*+NO_MERGE*/ x, AVG(y) AS avg_y FROM t2 GROUP BY x) v,
   WHERE t1.x = v.x AND t1.y = 1;

通常、このヒントは、データベース環境の情報に基づいて最適化した問合せを作成したときに使用します。

DRIVING_SITEヒントの使用

DRIVING_SITEヒントを使用すると、問合せを実行するサイトを指定できます。問合せを実行するサイトはコストベース最適化によって決定されるのが最適ですが、オプティマイザの判断を変更する方がよい場合は、実行サイトを手動で指定できます。

DRIVING_SITEヒントを使用したSELECT文の例を次に示します。

SELECT /*+DRIVING_SITE(dept)*/ * FROM emp, dept@remote.com
   WHERE emp.deptno = dept.deptno;

実行計画の分析

分散問合せのチューニングの際に重要なこととして、実行計画の分析があります。分析結果から得られるフィードバックは、データベースのテストと検証を行う上で重要な要素になります。計画を比較するときは、検証が特に重要になります。たとえば、コストベースの最適化によって分散問合せを最適化する実行計画を、ヒント、連結インライン・ビューおよびその他の方法を使用して問合せを手動で最適化する計画と比較します。

関連項目:

実行計画、EXPLAIN PLAN文およびその結果の解釈方法の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。 

計画を格納するためのデータベースの準備

分散問合せの実行計画を表示できるようにするには、まずデータベース内に実行計画を格納する場所を準備します。そのために、スクリプトを実行します。次のスクリプトを実行し、データベース内に実行計画を格納する場所を準備します。

SQL> @UTLXPLAN.SQL


注意:

utlxplan.sqlファイルは、$ORACLE_HOME/rdbms/adminディレクトリにあります。  


utlxplan.sqlを実行すると、現行スキーマ内に、実行計画を一時的に格納するPLAN_TABLEという表が作成されます。

実行計画の生成

データベース内に実行計画を格納する場所を準備すると、指定した問合せの計画を表示するための準備が完了します。SQL文を直接実行するかわりに、EXPLAIN PLAN FOR句に文を追加します。たとえば、次のような文を実行できます。

EXPLAIN PLAN FOR
   SELECT d.dname 
   FROM dept d
      WHERE d.deptno 
      IN (SELECT deptno 
          FROM emp@orc2.world
          GROUP BY deptno
          HAVING COUNT (deptno) >3
          )
/

実行計画の表示

前述のSQL文を実行すると、すでに作成したPLAN_TABLEに実行計画が一時的に格納されます。実行計画の結果を表示するには、次のスクリプトを実行します。

@UTLXPLS.SQL


注意:

utlxpls.sqlファイルは$ORACLE_HOME/rdbms/adminディレクトリにあります。 


utlxpls.sqlスクリプトを実行すると、指定したSELECT文の実行計画が表示されます。結果は、次のように書式化されます。

Plan Table
-------------------------------------------------------------------------------
| Operation                 |  Name    |  Rows | Bytes|  Cost  | Pstart| Pstop |
-------------------------------------------------------------------------------
| SELECT STATEMENT          |          |       |      |        |       |      |
|  NESTED LOOPS             |          |       |      |        |       |      |
|   VIEW                    |          |       |      |        |       |      |
|    REMOTE                 |          |       |      |        |       |      |
|   TABLE ACCESS BY INDEX RO|DEPT      |       |      |        |       |      |
|    INDEX UNIQUE SCAN      |PK_DEPT   |       |      |        |       |      |
-------------------------------------------------------------------------------

独自の連結インライン・ビューを記述するか、またはヒントを使用して、分散問合せを手動で最適化しようとする場合は、手動最適化の前および後に実行計画を生成するのが最適です。これら両方の実行計画を使用することで、手動最適化の効果を比較し、必要に応じて変更を加え、分散問合せのパフォーマンスを改善できます。

リモート・サイトで実行されるSQL文を表示するには、次のSELECT文を実行します。

SELECT OTHER 
FROM PLAN_TABLE 
   WHERE operation = 'REMOTE';

出力例を次に示します。

SELECT DISTINCT "A1"."DEPTNO" FROM "EMP" "A1" 
   GROUP BY "A1"."DEPTNO" HAVING COUNT("A1"."DEPTNO")>3


注意:

OTHER列の内容全体がうまく表示されない場合は、次のSQL*Plusコマンドを実行してください。

SET LONG 9999999 
 

リモート・プロシージャのエラー処理

データベースがプロシージャをローカルまたはリモートの位置で実行するときには、次の4種類の例外が発生する可能性があります。

ローカル・プロシージャを使用するときは、次のような例外ハンドラを記述して、これらのメッセージをトラップできます。

BEGIN
  ...
EXCEPTION
   WHEN ZERO_DIVIDE THEN
   /* ... handle the exception */
END;

WHEN句には例外名が必要です。RAISE_APPLICATION_ERRORで生成された例外など、例外が名前を持っていない場合は、PRAGMA_EXCEPTION_INITを使用して名前を割り当てることができます。次に例を示します。

DECLARE
  null_salary EXCEPTION;
  PRAGMA EXCEPTION_INIT(null_salary, -20101);
BEGIN
  ...
  RAISE_APPLICATION_ERROR(-20101, 'salary is missing');
...
EXCEPTION
  WHEN null_salary THEN
  ...
END;

リモート・プロシージャをコールするときは、例外をローカル・プロシージャの例外ハンドラで処理できます。リモート・プロシージャは、エラー番号をローカルのコール側プロシージャに返す必要があります。ローカルのコール側プロシージャは、受け取った例外を前の例で示したように処理します。PL/SQLのユーザー定義例外は、常にORA-06510をローカル・プロシージャに返します。

したがって、2つの異なるユーザー定義例外をエラー番号で区別することはできません。その他のリモート例外はすべて、ローカル例外と同じ方法で処理できます。

関連項目:

PL/SQLプロシージャの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 


戻る 次へ
Oracle
Copyright © 2001, 2008, Oracle Corporation.
All Rights Reserved.
目次
目次
索引
索引