ある環境で開発した複数のモジュールを統合して、別の環境にデプロイするアプリケーション開発環境では、アプリケーションのパフォーマンスが影響を受けます。プリコンパイラ・アプリケーションのパフォーマンスは、データベース環境の変更によって影響を受けることがあります。これらの変更には、オプティマイザ統計の変更、オプティマイザ設定の変更またはメモリー構造のサイズに影響するパラメータの変更が含まれます。
開発環境においてPro*C/C++で使用されるSQLの実行計画を修正するには、プリコンパイル時にOracleのアウトライン機能を使用する必要があります。アウトラインは、SQL文と関連付けられた一連のオプティマイザ・ヒントとして実装されます。SQL文のアウトラインの使用を有効にすると、Oracleでは、格納されたヒントが自動的に考慮され、それらのヒントに従って実行計画を生成しようとします。これにより、モジュールの統合時および異なる環境へのデプロイ時に、パフォーマンスは影響を受けません。
次のSQL文を使用して、Pro*C/C++でアウトラインを作成できます。
SELECT
DELETE
UPDATE
INSERT ... SELECT
CREATETABLE...ASSELECT
アウトライン・オプションが設定されている場合、プリコンパイルが正常に終了すると、2つのファイル(SQLファイルおよびLOGファイル)が生成されます。コマンドライン・オプションoutline
およびoutlnprefix
は、アウトラインの生成を制御します。
生成される各アウトライン名は一意です。アプリケーションで使用するファイル名が一意であるため、アウトライン名の生成時にこの情報が使用されます。また、カテゴリ名も接頭辞として使用されます。
注意:
アウトライン名の最大長は30バイトです。この制限を超えると、プリコンパイラではエラーが発生します。outlnprefix
オプションを使用すると、アウトライン名の長さを制限できます。
例6-1 アウトラインを含むSQLファイルの生成
次のプログラムのアウトラインがサポートされているすべてのSQL文のアウトラインを含むSQLファイルを生成するには、アウトライン・オプションを使用して、次のプログラムをプリコンパイルする必要があります。
/* * outlndemo.pc * * Outlines will be created for the following SQL operations, * 1. CREATE ... SELECT * 2. INSERT ... SELECT * 3. UPDATE * 4. DELETE * 5. SELECT */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlda.h> #include <sqlcpr.h> #include <sqlca.h> /* Error handling function. */ void sql_error(char *msg) { exec sql whenever sqlerror continue; printf("\n%s\n", msg); printf("%.70s\n", sqlca.sqlerrm.sqlerrmc); exec sql rollback release; exit(EXIT_FAILURE); } int main() { varchar ename[10]; varchar job[9]; float sal, comm; exec sql begin declare section; char *uid = "scott/tiger"; exec sql end declare section; exec sql whenever sqlerror do sql_error("ORACLE error--\n"); exec sql connect :uid; exec sql insert into bonus select ename, job, sal, comm from emp where job like 'SALESMAN'; exec sql update bonus set sal = sal * 1.1 where sal < 1500; exec sql declare c1 cursor for select ename, job, sal, comm from bonus order by sal; exec sql open c1; printf ("Contents of updated BONUS table\n\n"); printf ("ENAME JOB SALARY COMMISSION\n\n"); exec sql whenever not found do break; while (1) { exec sql fetch c1 into :ename, :job, :sal, :comm; ename.arr[ename.len]='\0'; job.arr[job.len]='\0'; printf ("%-9s %-9s %8.2f %8.2f\n", ename.arr, job.arr, sal, comm); } exec sql close c1; exec sql whenever not found do sql_error("ORACLE error--\n"); exec sql delete from bonus; exec sql create table outlndemo_tab as select empno, ename, sal from emp where deptno = 10; /* Outline will not be created for this DDL statement */ exec sql drop table outlndemo_tab; exec sql rollback work release; exit(EXIT_SUCCESS); }
生成されるファイル名の書式は次のとおりです。
<filename>_<filetype>.sql
Pro*Cでは、ファイル「abc.pc」の場合、生成されるSQLファイルはabc_pc.sqlになります。
生成されるファイル書式
outlnprefixオプションを使用しない場合は、アウトライン名およびコメントとして、次の一意識別子の書式が使用されます。
<category_name>_<filename>_<filetype>_<sequence no.>
outlnprefixオプションを使用する(outlnprefix=<prefix_name>)場合は、アウトライン名およびコメントとして、次の一意識別子の書式が使用されます。
<prefix_name>_<sequence no.>
outline=yes (デフォルトのカテゴリ)の場合、<category_name>はDEFAULTに、アウトライン名は次のいずれかになります。
DEFAULT_<filename>_<filetype>_<sequence no.>
または
<prefix_name>_<sequence no.>
<sequence no.>
に使用できる値の範囲は、0000から9999です。
生成されたプリコンパイル済ファイルのSQLには、SQLのアウトラインで表示されるように、コメントが追加されます。
次の例を考えてみます。
例1
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp where empno=:var; EXEC SQL select * from dept;
outline=mycat1で、outlnprefixを使用しない場合は、次のようになります。
abc_pc.sqlの内容
select * from emp where empno=:b1 /* mycat1_abc_pc_0000 */
;
で、カテゴリmycat1のアウトラインmycat1_abc_pc_0000を作成または置換します。
select * from dept /* mycat1_abc_pc_0001 */;
で、カテゴリmycat1のアウトラインmycat1_abc_pc_0001を作成または置換します。
abc.cの内容
sqlstm.stmt = select * from emp where empno=:b1 /* mycat1_abc_pc_0000 */; sqlstm.stmt = select * from dept /* mycat1_abc_pc_0001 */;
例2
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp where empno=:var; EXEC SQL select * from dept;
outline=mycat1で、outlnprefix=myprefixの場合は、次のようになります。
abc_pc.sqlの内容
select * from emp where empno=:b1 /* myprefix_0000 */;
で、カテゴリmycat1のアウトラインmyprefix_0000を作成または置換します。
select * from dept /* myprefix_0001 */;
で、カテゴリmycat1のアウトラインmyprefix_0001を作成または置換します。
abc.cの内容
sqlstm.stmt = select * from emp where empno=:b1 /* myprefix_0000 */; sqlstm.stmt = select * from dept /* myprefix_0001 */;
例3
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp where empno=:var; EXEC SQL select * from dept;
outline=yesで、outlnprefix=myprefixの場合は、次のようになります。
abc_pc.sqlの内容
select * from emp where empno=:b1 /* myprefix_0000 */;
で、アウトラインmyprefix_0000を作成または置換します。
select * from dept /* myprefix_0001 */;
で、アウトラインmyprefix_0001を作成または置換します。
abc.cの内容
sqlstm.stmt = "select * from emp where empno=:b1 /* myprefix_0000 */; sqlstm.stmt = "select * from dept /* myprefix_0001 */";
生成されるファイル名の書式は次のとおりです。
<filename>_<filetype>.log
Pro*Cでは、ファイル「abc.pc」の場合、生成されるLOGファイルはabc_pc.logになります。
次に例を示します。
例1
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp;
abc_pc.logの内容
CATEGORY <Category_name> Source SQL_0 SELECT * FROM emp OUTLINE NAME abc_pc_0000 OUTLINE SQL_0 Select * from emp /* abc_pc_0000 */