問合せオプティマイザの使用による最適な計画の選択
複数の実行計画が可能な場合、TimesTenによってSQL文用のオプティマイザが起動されます。オプティマイザは、最適と判断した計画を選択します。この計画は、文がアプリケーションによって無効にされるか削除されるまで保持されます。
文は次の状況で自動的に無効化されます。
-
コマンドが使用するオブジェクトが破棄された
-
コマンドが使用するオブジェクトが変更された
-
コマンドが参照する表またはビューの索引が破棄された
-
コマンドが参照する表またはビューに索引が作成された
次のいずれかの方法を使用して、文を手動で無効化できます。
-
ttOptCmdCacheInvalidate
組込みプロシージャを使用してSQLコマンド・キャッシュ内の文を無効化します。「SQLコマンド・キャッシュ内のコマンドの無効化の制御」を参照してください。 -
ttOptUpdateStats
またはttOptEstimateStats
組込みプロシージャで、invalidation
オプションを1に設定します。これらの組込みプロシージャによって、指定した表または現在のユーザーが所有するすべての表の統計も更新されます。
ノート:
統計を計算するタイミングの詳細は、「正確な統計または見積り統計の計算」を参照してください。また、『Oracle TimesTen In-Memory Databaseリファレンス』のttOptUpdateStatsまたはttOptEstimateStatsを参照してください。
無効化された文は、通常は、再実行される直前に自動的に再準備されます。つまり、その時点でオプティマイザが再度起動され、場合によっては新しい計画が作成されます。したがって、1つのコマンドが何度も準備されることがあります。
ノート:
JDBCを使用しているときは、表が変更された場合に、文を手動で再度準備する必要があります。
たとえば、文で参照していた表が破棄され、同じ名前の表が作成されたときには、文を手動で準備することが必要な場合があります。文を手動で準備する場合は、準備文を、共有できるようにコミットする必要があります。文が、無効なため再コンパイルされる場合、および参照されているいずれかの表で使用されているDDLが再コンパイルに必要な場合は、準備文をコミットしてコマンド・ロックを解放する必要があります。
たとえば、ODBCでは、表T1
とT2
を結合するコマンドによって、次のような処理が行われます。
処理 | 説明 |
---|---|
|
コマンドが準備されます。 |
|
コマンドが実行されます。 |
|
コマンドが再実行されます。 |
T1に対する索引の作成 |
コマンドが無効化されます。 |
|
コマンドが再度準備され、実行されます。 |
|
コマンドが再実行されます。 |
T1に対する |
コマンドが無効になります(無効フラグが |
|
コマンドが再度準備され、実行されます。 |
|
コマンドが再実行されます。 |
|
コマンドがコミットされます。 |
|
コマンドが破棄されます。 |
JDBCでは、表T1
とT2
を結合するコマンドによって、次のような処理が行われます。
処理 | 説明 |
---|---|
|
コマンドが準備されます。 |
|
コマンドが実行されます。 |
|
コマンドが再実行されます。 |
T1に対する索引の作成 |
コマンドが無効化されます。 |
|
コマンドが再度準備され、実行されます。 |
|
コマンドが再実行されます。 |
T1に対する |
コマンドが無効になります(無効フラグが |
|
コマンドが再度準備され、実行されます。 |
|
コマンドが再実行されます。 |
|
コマンドがコミットされます。 |
|
コマンドが破棄されます。 |
前述のとおり、最適化は、通常は準備のときに実行されますが、後で索引が破棄または作成されるときや、統計が変更されるときにも実行されることがあります。キャッシュ内のコマンドを準備で使用できる場合は、最適化は行われません。
コマンドの準備時にgenPlan
フラグが設定されていた場合は、同じフラグが設定されて再度コンパイルされます。したがって、別の問合せのための計画がSYS.PLAN
表内にある場合でも、計画は作成されます。
オプティマイザの動作をに影響を与えるオプティマイザ・ヒントをアプリケーションで指定した場合、これらのヒントはコマンドを削除するまで維持されます。「SQL問合せ実行計画の変更」を参照してください。たとえば、同じハンドルでODBC SQLPrepare
関数またはJDBC Connection.prepareStatement()
メソッドが再度コールされた場合や、SQLFreeStmt
関数またはPreparedStatement.close()
メソッドがコールされた場合などです。つまり、無効化が原因となって発生するすべての中間の再準備で、同じヒントが使用されることになります。