Q6.9: Stored Procedure Recompilation and Reresolution


When a stored procedure is created, the text is placed in syscomments and a parse tree is placed in sysprocedures. At this stage there is no compiled query plan.

A compiled query plan for the procedure only ever exists in memory (that is, in the procedure cache) and is created under the following conditions:

  1. A procedure is executed for the first time.
  2. A procedure is executed by a second or subsequent user when the first plan in cache is still in use.
  3. The procedure cache is flushed by server restart or cache LRU flush procedure.
  4. The procedure is executed or created using the with recompile option.

If the objects the procedure refers to change in some way - indexes dropped, table definition changed, etc - the procedure will be reresolved - which updates sysprocedures with a modified tree. Before 10.x the tree grows and in extreme cases the procedure can become too big to execute. This problem disappears in Sybase System 11. This reresolution will always occur if the stored procedure uses temporary tables (tables that start with "#").

There is apparently no way of telling if a procedure has been reresolved.

Traceflag 299 offers some relief, see Q1.4 for more information regarding traceflags.

The Official Explanation -- Reresolution and Recompilation Explained

When stored procedures are created, an entry is made in sysprocedures that contains the query tree for that procedure. This query tree is the resolution of the procedure and the applicable objects referenced by it. The syscomments table will contain the actual procedure text. No query plan is kept on disk. Upon first execution, the query tree is used to create (compile) a query plan (execution plan) which is stored in the procedure cache, a server memory structure. Additional query plans will be created in cache upon subsequent executions of the procedure whenever all existing cached plans are in use. If a cached plan is available, it will be used.

Recompilation is the process of using the existing query tree from sysprocedures to create (compile) a new plan in cache. Recompilation can be triggered by any one of the following:

Re-resolution is the process of updating the query tree in sysprocedures AND recompiling the query plan in cache. Re-resolution only updates the query tree by adding the new tree onto the existing sysprocedures entry. This process causes the procedure to grow in size which will eventually cause an execution error (Msg 703 - Memory request failed because more than 64 pages are required to run the query in its present form. The query should be broken up into shorter queries if possible). Execution of a procedure that has been flagged for re-resolution will cause the re-resolution to occur. To reduce the size of a procedure, it must be dropped which will remove the entries from sysprocedures and syscomments. Then recreate the procedure.

Re-resolution can be triggered by various activities most of which are controlled by SQL Server, not the procedure owner. One option is available for the procedure owner to force re-resolution. The system procedure, sp_recompile, updates the schema count in sysobjects for the table referenced. A DBA usually will execute this procedure after creating new distribution pages by use of update statistics. The next execution of procedures that reference the table flagged by sp_recompile will have a new query tree and query plan created. Automatic re-resolution is done by SQL Server in the following scenarios:

Forcing automatic compression of procedures in System 10 is done with trace flag 241. System 11 should be doing automatic compression, though this is not certain.

When are stored procedures compiled?

Stored procedures are in a database as rows in sysprocedures, in the form of parse trees. They are later compiled into execution plans.

A stored procedures is compiled:

  1. with the first EXECute, when the parse tree is read into cache
  2. with every EXECute, if CREATE PROCEDURE included WITH RECOMPILE
  3. with each EXECute specifying WITH RECOMPILE
  4. if the plans in cache for the procedure are all in use by other processes
  5. after a LOAD DATABASE, when all procedures in the database are recompiled
  6. if a table referenced by the procedure can not be opened (using object id), when recompilation is done using the table's name
  7. after a schema change in any referenced table, including:
    1. CREATE INDEX or DROP INDEX to add/delete an index
    2. ALTER TABLE to add a new column
    3. sp_bindefault or sp_unbindefault to add/delete a default
    4. sp_bindrule or sp_unbindrule to add/delete a rule
  8. after EXECute sp_recompile on a referenced table, which increments sysobjects.schema and thus forces re-compilation

What causes re-resolution of a stored procedure?

When a stored procedure references an object that is modified after the creation of the stored procedure, the stored procedure must be re-resolved. Re-resolution is the process of verifying the location of referenced objects, including the object id number. Re-resolution will occur under the following circumstances:
  1. One of the tables used by the stored procedure is dropped and re-created.
  2. A rule or default is bound to one of the tables (or unbound).
  3. The user runs sp_recompile on one of the tables.
  4. The database the stored procedure belongs to is re-loaded.
  5. The database that one of the stored procedure's tables is located in is re-loaded.
  6. The database that one of the stored procedure's tables is located in is dropped and re-created.

What will cause the size of a stored procedure to grow?

Any of the following will result in a stored procedure to grow when it is recompiled:
  1. One of the tables used in the procedure is dropped and re-created.
  2. A new rule or default is bound to one of the tables or the user runs sp_recompile on one of the tables.
  3. The database containing the stored procedure is re-loaded.
Other things causing a stored procedure to be re-compiled will not cause it to grow. For example, dropping an index on one of the tables used in the procedure or doing EXEC WITH RECOMPILE.

The difference is between simple recompilation and re-resolution. Re-resolution happens when one of the tables changes in such a way that the query trees stored in sysprocedures may be invalid. The datatypes, column offsets, object ids or other parts of the tree may change. In this case, the server must re-allocate some of the query tree nodes. The old nodes are not de-allocated (there is no way to do this within a single procedure header), so the procedure grows. In time, trying to execute the stored procedure will result in a 703 error about exceeding the 64 page limit for a query.