Most SQL statements have an associated Query Plan. A query plan is created when an SQL statement is prepared. By default, operations such as adding an index and recompiling the class purge this Query Plan. The next time the query is invoked it is re-prepared and a new Query Plan is created. Frozen plans enable you to retain (freeze) a existing Query Plan across compiles. Query execution uses the frozen plan, rather than performing a new optimization and generating a new query plan.
Changes to system software may also result in a different Query Plan. Usually, these upgrades result in better query performance, but it is possible that a software upgrade may worsen the performance of a specific query. Frozen plans enable you to retain (freeze) a Query Plan so that query performance is not changed (degraded or improved) by a system software upgrade.
There are two strategies for using frozen plans the optimistic strategy and the pessimistic strategy:
Pessimistic: use this strategy if your assumption is that a change to the system software or to a class definition will probably not improve performance of a specific query. Run the query and freeze the plan
. Make the software change. Re-run the query with the %NOFPLAN
keyword (which causes the frozen plan to be ignored). Compare the performance of the two queries. If ignoring the frozen plan did not improve performance, keep the plan frozen and remove %NOFPLAN from the query.
When you upgrade Caché to a new major version, existing Query Plans are automatically frozen. This ensures that a major software upgrade will never degrade the performance of an existing query. After a software version upgrade, perform the following steps for performance-critical queries:
Execute the query with the plan state as Frozen/Upgrade and monitor performance. This is the optimized Query Plan that was created prior to the software upgrade.
Add the %NOFPLAN
keyword to the query, then execute and monitor performance. This optimizes the Query Plan using the SQL optimizer provided with the software upgrade. It does not unfreeze the existing Query Plan.
Compare the performance metrics.
If the %NOFPLAN performance is better, the software upgrade improved the Query Plan. Unfreeze the Query Plan. Remove the %NOFPLAN keyword.
If the %NOFPLAN performance is worse, the software upgrade degraded the Query Plan. Keep the Query Plan frozen; promote it from Frozen/Upgrade to Frozen/Explicit. Remove the %NOFPLAN keyword.
After testing your performance-critical queries, you can unfreeze all remaining Frozen/Upgrade plans.
This automatic freeze occurs when you prepare/compile a query under a Caché version newer than the version under which the plan was originally created. For example, consider an SQL statement that was prepared/compiled under Caché version 2016.2. You then upgrade Caché to version 2017.1, and the SQL statement is prepared/compiled again. The system will detect this is the first prepare/compile of the SQL statement on the new version, and automatically marks the plan state as Frozen/Upgrade, and uses the existing plan for the new prepare/compile. This ensures the query plan used is no worse than the query plan of the previous version.
Only major version Caché upgrades automatically freeze existing query plans. The earliest upgrade that performs this operation is an upgrade from 2016.2.0. For example, a major version upgrade, such as from 2016.2 to 2017.1, or from 2017.1 to 2017.2 performs this operation. A maintenance release version upgrade, such as 2017.1.0 to 2017.1.1 does not perform this operation.
In the Management Portal SQL interface the SQL Statements Plan State
column indicates these automatically frozen plans as Frozen/Upgrade and the Plan Version
indicates the Caché version of the original plan. Refer to SQL Statement Details
for further information. You can unfreeze individual plans using this interface.
You can use the FreezePlans()
method to freeze or unfreeze a single plan or multiple plans:
can unfreeze Frozen/Upgrade query plans within the specified scope: namespace, schema, relation (table), or individual query.
can promote (freeze) query plans flagged as Frozen/Upgrade to Frozen/Explicit. Commonly, you would use this method to selectively promote appropriate Frozen/Upgrade plans to Frozen/Explicit, then unfreeze all remaining Frozen/Upgrade plans.
An upgrade from Caché version 2016.2 to a later version does not change INSERT ... SELECT
query plans to Frozen/Upgrade. If the plan state was Unfrozen, the plan state for these statements will remain Unfrozen. If the plan state was Frozen, the plan will be put in an error state and will be unusable; you must explicitly unfreeze the plan. Following upgrade, you should recompile the container code (routine, class) that contains the INSERT ... SELECT
statement, or purge and re-prepare cached queries. You can then re-freeze formerly frozen plans, if desired.
There are two frozen plan interfaces, used for different purposes:
Management Portal SQL Statements
interface, used to freeze (or unfreeze) the plan for an individual query.
method interface, used to freeze or unfreeze all plans for a namespace, a schema, a table, or an individual query.
In the Management Portal SQL interface select the Execute Query
tab. Write a query, then click the Show Plan
button to display the current query execution plan. If the plan is frozen, the first line in the Query Plan section is Frozen Plan
button: Clicking this button will cause the query optimization plan for this statement to be frozen. When a plan is frozen, and that SQL statement is compiled, the SQL compilation will use the frozen plan information and skip the query optimization phase.
button: Clicking this button will delete the frozen plan for this statement and new compilations of this statement will go through query optimization phase to determine the best plan to use.
You can also freeze or unfreeze one or more plans using the FreezePlans()
method. You can specify the scope of the freeze or unfreeze operation by specifying the namespace, the SQL schema name, the SQL schema.table name, or the query plan statement specified by the SQL Statement hash value.
Management Portal SQL Statements
access requires USE privilege on the %Development resource. Any user that can see an SQL Statement in the Management Portal can freeze or unfreeze it.
For catalog access to SQL Statements, you can see the statements if you are privileged to execute the statement or you have USE privilege on the %Development resource.
For the $SYSTEM.SQL.FreezePlan() method call, you must have U privilege on the %Developer resource.
If a plan is frozen, you can determine if unfreezing the plan would result in a different plan without actually unfreezing the plan. This information can assist you in determining which SQL statements are worth testing using %NOFPLAN
to determine if unfreezing the plan would result in better performance.
A frozen plan may be different from the current query plan due to any of the following operations:
These operations may or may not result in a different query plan. There are two ways to determine if they do:
Manually checking individual frozen plans
Automatically scanning all frozen plans on a daily basis
If the plan has not yet been checked by either of these operations, or a plan is not frozen, the SQL Statements listing New Plan
column is blank. Unfreezing a checked frozen plan resets the New Plan
column to blank.
When you have performed this Check frozen
test on a frozen plan:
If the Unfrozen plan different
box is checked, the SQL Statements listing New Plan
column contains a 1. This indicates that unfreezing the plan would result in a different plan.
If the Unfrozen plan different
box is not checked, the SQL Statements listing New Plan
column contains a 0. This indicates that unfreezing the plan would not result in a different plan.
A cached query
that has been frozen has a New Plan
of 0; purging the cached query and then unfreezing the plan causes the SQL statement to disappear.
Automatic Daily Frozen Plan Check
Caché SQL automatically scans all frozen statements in the SQL Statement listing every night at 2:00am. This scan lasts for, at most, one hour. If the scan is not completed in one hour, Caché notes where it left off, and continues from that point on the next daily scan. You can use the Management Portal
to monitor this daily scan or to force it to scan immediately: select System Operation
, Task Manager
, Task Schedule
, then select the Scan frozen plans
This scan examines all frozen plans:
If the frozen plan has the same Caché version as the current version, Caché compute a hash on all the tables that this plan references and their timestamps. If any of these have changed, it flags the SQL statement in the SQL Statements listing New Plan
column with a 1. This indicates that unfreezing the plan would result in a different query plan.
If the frozen plan has the same Caché version as the current version, and no table timestamps have changed, it flags the SQL statement in the SQL Statements listing New Plan
column with a 0. This indicates that unfreezing the plan would not result in a different query plan.
If the frozen plan has a different Caché version from the current version (Frozen/Update
), Caché determines if a change to the SQL optimizer logic would result in a different query plan. If so, it flags the SQL statement in the SQL Statements listing New Plan
column with a 1. Otherwise, it flags the SQL statement New Plan
column with a 0.
You can check the results of this scan by invoking INFORMATION_SCHEMA.STATEMENTS
. The following example returns the SQL Statements for all frozen plans, indicating whether the frozen plan is different from what the plan would be if not frozen. Note that an unfrozen statement may be Frozen=0 or Frozen=3:
SELECT Frozen,FrozenDifferent,Timestamp,Statement FROM INFORMATION_SCHEMA.STATEMENTS
WHERE Frozen=1 OR Frozen=2
If a statement's plan is frozen, and something changes to a definition used by the plan to cause the plan to be invalid, an error occurs. For example, if an index was deleted from the class that was used by the statement plan:
If the query is [re]compiled and the frozen plan is in an error state, Caché does not use the frozen plan. Instead, the system creates a new Query Plan that will work given the current definitions. However, this Query Plan is not preserved in a cached query or an SQL Statement if a frozen plan is in effect.
The plan in error remains in error until either the plan is unfrozen, or the definitions are modified to bring the plan back to a valid state.
If you modify the definitions to bring the plan back to a valid state, go to the SQL Statement Details page and press the Clear Error
button to determine if you have corrected the error. If corrected, the Plan Error
field disappears; otherwise the Plan Error
message re-displays. If you have corrected the definition, you do not have to explicitly clear the plan error for Caché to begin using the frozen plan. If you have corrected the definition, the Clear Error
button causes the SQL Statement Details page Frozen Query Plan
area to again display the execution plan.
A Plan Error
may be a soft error. This can occur when the plan uses an index, but that index is currently not selectable by the query optimizer because its selectability has been set to 0 by SetMapSelectability()
. This was probably done so the index could be [re]built. When Caché encounters a soft error for a statement with a frozen plan, the query processor attempts to clear the error automatically and use the frozen plan. If the plan is still in error, the plan is again marked in error and query execution uses the best plan it can.
You can use the %NOFPLAN keyword to override a frozen plan. An SQL statement containing the %NOFPLAN keyword generates a new query plan. The frozen plan is retained but not used. This allows you to test generated plan behavior without losing the frozen plan.
The syntax of %NOFPLAN is as follows:
DECLARE <cursor name> CURSOR FOR SELECT %NOFPLAN ...
SELECT %NOFPLAN ....
INSERT [OR UPDATE] %NOFPLAN ...
DELETE %NOFPLAN ...
In a SELECT
statement the %NOFPLAN keyword can only be used immediately after the first SELECT
in the query: it can only be used with the first leg of a UNION
query, and cannot be used in a subquery. The %NOFPLAN keyword must immediately follow the SELECT
keyword, preceding other keywords such as DISTINCT or TOP.
You can export or import SQL Statements. This enables you to move a frozen plan from one location to another. SQL Statement exports and imports include the associated query plan.
To import an SQL Statement or multiple SQL Statements from a file, use the ImportSQLStatement()