the data in a database changes over time
This is the usual reason. While the concept of compiling a stored procedure is implementation specific, it usually involves producing a query plan for the procedure and/or the individual statements it is formed from, and storing it for later reuse (to save that part of the process being repeated every time the procedure is called).
As your data grows, the balance of data in each table/index may change in such a way that the optimal plan when the procedure was last compiled is now much more inefficient than other options so the procedure will no longer be performing as well as it could. If you had just a few rows in a table when the procedure was created (or last compiled) a scan might have been more efficient than one or more seeks for instance, but that may no longer be the case later. Also which index it is most efficient to touch first can change over time especially for queries on wide tables and those that join in several tables.
The database engine will usually have some heuristics built in to cause a recompile after massive data changes, as well as after structural changes, but these are usually quite conservative in their action so manually kicking off a recompile is sometimes necessary. Much the same as the heuristics involved in deciding when to resample index statistics histograms (which in tern feeds into the query plan decisions generally and in your stored procs).
Sometimes procs with parameters will need different plans to be efficient for different inputs - sometimes there are circumstances where it is beneficial to always for a recompile because the difference is so high that you don't want to risk using a slow cached plan (in MS SQL Server the
WITH RECOMPILE hint is there to deal with such circumstances, or the per-statement
OPTION (RECOMPILE) for a finer grained approach). Procedures complex enough that this is a major issue are often "code smells" which mean your design needs a tweak, though they are not always easily avoidable.
A final reason to recompile stored procedures, functions, views, and other programmatic objects, is when changes elsewhere are made in a way that breaks dependency checking, meaning an automatic recompile does not happen when it is actually needed. For instance:
- You have a proc that uses a view on a table.
- Someone drops and recreates the view (instead of using
The dependency information proc->view is now lost.
- The table is altered.
As the dependency chain is broken, the engine does not know that the statements in the procedure may need to be recompiled meaning that procedure may start failing completely or giving incorrect results.
- A recompile (at this stage or after the view was recreated) fixes this.