この項では、実行計画の変更がなぜ必要になるのか、およびその変更方法について説明します。
アプリケーションでは次の2つの理由で、実行計画を変更することがあります。
またオプティマイザが選択した計画で消費するメモリーが、実際の利用可能な容量より多かったり、アプリケーションで割り当てようとする容量より多い場合もあります。たとえば、計画で中間的な処理結果を保持したり、一時索引の作成が必要な場合に、このような容量不足が発生します。
アプリケーションは、オプティマイザにヒントを指定することによって、問合せ計画を変更できます。ヒントは、TimesTenオプティマイザの組込みプロシージャをコールして指定します(「実行計画の生成を変更する方法」を参照)。このヒントは、トランザクションにある、ODBC SQLPrepare関数またはJDBC PreparedStatementオブジェクトに対するすべてのコールで有効です。
特定のヒントが有効になっている状態でコマンドの準備が実行されると、コマンドが自動的に再度準備されても、そのヒントは引き続き適用されます。つまり、準備のトランザクション自体が終わっても、ヒントはそのまま残ることになります。このような問題は、「最適化を実行するタイミング」で説明したとおり、表の変更、索引の作成または破棄、あるいは統計の変更が行われたときに発生します。
ヒントなしでコマンドを準備している場合は、コマンドが自動的に再準備されても、コマンドがその後のヒントの影響を受けることはありません。ヒントを有効にするには、アプリケーションでもう一度ODBC SQLPrepare関数またはJDBC Connection.prepareStatementメソッドをコールする必要があります。
ODBCを使用する場合に開発者がT1とT2の結合を調整するには、次のような手順を実行することになります。
処理を開始すると、アプリケーションは次のような手順で実行されます(ユーザーが特に介入しない場合)。
JDBCを使用する場合に開発者がT1とT2の結合を調整するには、次のような手順を実行することになります。
処理を開始すると、アプリケーションは次のような手順で実行されます(ユーザーが特に介入しない場合)。
問合せオプティマイザの動作を変更するには、ODBCプロシージャ・コール・インタフェースを使用して、アプリケーションで次の組込みプロシージャのいずれかをコールします。
プロシージャttOptSetFlagは、特定のオプティマイザ・パラメータを設定します。ttOptSetOrderを使用すると、表の結合順序をアプリケーションで指定できます。プロシージャttOptUseIndexを使用すると、アプリケーションで特定の索引を無効化できます。その他のプロシージャは、アプリケーション・データに関してTimesTen Data Managerが保守している統計を処理するためのものです。問合せオプティマイザは、これらの統計を使用して様々な処理のコストを予測します。『Oracle TimesTen In-Memory Database APIおよびSQLリファレンス・ガイド』の組込みプロシージャに関する章を参照してください。
次のODBCの例は、ttOptSetFlagを使用して、オプティマイザがマージ結合を選択しないようにする方法を示しています。
import java.sql.*; class Example { public void myMethod() { CallableStatement cStmt; PreparedStatement pStmt; . . . . . try { . . . . . . . // Prevent the optimizer from choosing Merge Join cStmt = con.prepareCall("{ CALL ttOptSetFlag('MergeJoin', 0)}"); cStmt.execute(); // Next prepared query pStmt=con.prepareStatement( "SELECT * FROM Tbl1, Tbl2 WHERE Tbl1.ssn=Tbl2.ssn"); . . . . . . . catch (SQLException ex) { ex.printStackTrace(); } } . . . . . . . }
次のJDBCの例は、ttOptSetFlagを使用して、オプティマイザがマージ結合を選択しないようにする方法を示しています。
#include <sql.h> SQLRETURN rc; SQLHSTMT hstmt; fetchStmt; .... rc = SQLExecDirect (hstmt, (SQLCHAR *) "{CALL ttOptSetFlag (MergeJoin, 0)}", SQL_NTS) /* check return value */ ... rc = SQLPrepare (fetchStmt, ...) /* check return value */ ...ttIsqlユーティリティを使用して、オプティマイザの設定を試すこともできます。tryで始まるコマンドは、オプティマイザのヒントを制御します。現在のオプティマイザのヒント設定を確認するには、optprofileコマンドを使用します。