1つのコマンドが何度も最適化されることがあるため、TimesTenがどのようなタイミングで問合せの最適化を実行するのか理解しておくことをお薦めします。
オプティマイザは、ODBCのSQLPrepareまたはSQLExecDirect関数あるいはJDBCのいずれかの実行メソッドによってSELECT文、UPDATE文、DELETE文、INSERT SELECT文またはCREATE MATERIALIZED VIEW文が準備されると、必ず起動されます。作成された計画は、それを無効にするイベントが発生するか、またはそのコマンドがアプリケーションによって破棄されるまで保持されます。コマンドは、次の場合に無効になります。
無効になったコマンドは、通常、再実行される直前に再度自動的に準備されます。つまり、その時点でオプティマイザが再度起動され、場合によっては新しい計画が作成されます。このように、1つのコマンドが何度も準備されることがあります。
注意: | JDBCを使用するときは、表が変更された場合に、コマンドを手動で再度準備する必要があります。 |
たとえば、コマンドで参照していた表が破棄され、同じ名前の表が作成されたときには、コマンドを手動で準備することが必要な場合があります。文を手動で準備する場合は、準備文を、共有できるようにコミットする必要があります。コマンドが、無効なため再コンパイルされる場合、および参照されているいずれかの表で使用されているDDLが再コンパイルに必要な場合は、準備文をコミットしてコマンド・ロックを解放する必要があります。
たとえば、ODBCでは、表T1とT2を結合するコマンドによって、次のような処理が行われます。
JDBCでは、表T1とT2を結合するコマンドによって、次のような処理が行われます。
前述のとおり、最適化は、通常は準備のときに実行されますが、後で索引が破棄または作成されるときや、統計が変更されるときにも実行されることがあります。キャッシュ内のコマンドを準備で使用できる場合は、最適化は行われません。
コマンドの準備時にgenPlan
フラグが設定されていた場合は、同じフラグが設定されて再度コンパイルされます。したがって、別の問合せのための計画がSYS.PLAN表内にある場合でも、計画は作成されます。
オプティマイザの動作を変更するヒントをアプリケーションで指定した場合(「計画生成の変更」を参照)、これらのヒントはコマンドを削除するまで維持されます(たとえば、同じハンドルでODBC SQLPrepare関数またはJDBC Connection.prepareStatementメソッドが再度コールされた場合や、SQLFreeStmt関数またはPreparedStatement.closeメソッドがコールされた場合など)。つまり、無効化が原因となって発生するすべての中間の再準備で、同じヒントが使用されることになります。