この項では、実行計画の変更がなぜ必要になるのか、およびその変更方法について説明します。
アプリケーションでは次の2つの理由で、実行計画を変更することがあります。
またオプティマイザが選択した計画で消費するメモリーが、実際の利用可能な容量より多かったり、アプリケーションで割り当てようとする容量より多い場合もあります。たとえば、計画で中間的な処理結果を保持したり、一時索引の作成が必要な場合に、このような容量不足が発生します。
アプリケーションは、オプティマイザにヒントを指定することによって、問合せ計画を変更できます。ヒントは、TimesTenオプティマイザの組込みプロシージャをコールして指定します(「実行計画の生成を変更する方法」を参照)。このヒントは、トランザクションにある、ODBC SQLPrepare関数またはJDBC PreparedStatementオブジェクトに対するすべてのコールで有効です。
注意: | AUTOCOMMITが設定されていないことを確認してください。設定されている場合は、ttOptSetFlagプロシージャの実行後に現在のトランザクションが終了してしまい、次のトランザクションの準備を実行できなくなります。 |
特定のヒントが有効になっている状態でコマンドの準備が実行されると、コマンドが自動的に再度準備されても、そのヒントは引き続き適用されます。つまり、準備のトランザクション自体が終わっても、ヒントはそのまま残ることになります。このような問題は、「最適化を実行するタイミング」で説明したとおり、表の変更、索引の作成または破棄、あるいは統計の変更が行われたときに発生します。
ヒントなしでコマンドを準備している場合は、コマンドが自動的に再準備されても、コマンドがその後のヒントの影響を受けることはありません。ヒントを有効にするには、アプリケーションでもう一度ODBC SQLPrepare関数またはJDBC Connection.prepareStatementメソッドをコールする必要があります。
ODBCを使用する場合に開発者がT1とT2の結合を調整するには、次のような手順を実行することになります。
処理を開始すると、アプリケーションは次のような手順で実行されます(ユーザーが特に介入しない場合)。
JDBCを使用する場合に開発者がT1とT2の結合を調整するには、次のような手順を実行することになります。
処理を開始すると、アプリケーションは次のような手順で実行されます(ユーザーが特に介入しない場合)。
問合せオプティマイザの動作を変更するには、ODBCプロシージャ・コール・インタフェースを使用して、アプリケーションで次の組込みプロシージャのいずれかをコールします。
プロシージャttOptSetFlagは、特定のオプティマイザ・パラメータを設定します。ttOptSetOrderを使用すると、表の結合順序をアプリケーションで指定できます。プロシージャttOptUseIndexを使用すると、アプリケーションで特定の索引を無効化できます。その他のプロシージャは、アプリケーション・データに関してTimesTen Data Managerが保守している統計を処理するためのものです。問合せオプティマイザは、これらの統計を使用して様々な処理のコストを予測します。『Oracle TimesTen In-Memory Database APIリファレンス・ガイド』の組込みプロシージャに関する説明を参照してください。
例9.4に、ODBCでのttOptSetFlagの使用例を示します。例9.5は、JDBCでの例です。
次の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
コマンドを使用します。