add SQL Server index but how to recompile only affected stored procedures? - sql

I need to add an index to a table, and I want to recompile only/all the stored procedures that make reference to this table. Is there any quick and easy way?
EDIT:
from SQL Server 2005 Books Online, Recompiling Stored Procedures:
As a database is changed by such actions as adding indexes or changing data in indexed columns, the original query plans used to access its tables should be optimized again by recompiling them. This optimization happens automatically the first time a stored procedure is run after Microsoft SQL Server 2005 is restarted. It also occurs if an underlying table used by the stored procedure changes. But if a new index is added from which the stored procedure might benefit, optimization does not happen until the next time the stored procedure is run after Microsoft SQL Server is restarted. In this situation, it can be useful to force the stored procedure to recompile the next time it executes
Another reason to force a stored procedure to recompile is to counteract, when necessary, the "parameter sniffing" behavior of stored procedure compilation. When SQL Server executes stored procedures, any parameter values used by the procedure when it compiles are included as part of generating the query plan. If these values represent the typical ones with which the procedure is called subsequently, then the stored procedure benefits from the query plan each time it compiles and executes. If not, performance may suffer

You can exceute sp_recompile and supply the table name you've just indexed. all procs that depend on that table will be flushed from the stored proc cache, and be "compiled" the next time they are executed
See this from the msdn docs:
sp_recompile (Transact-SQL)

They are generally recompiled automatically. I guess I don't know if this is guaranteed, but it has been what I have observed - if you change (e.g. add an index) the objects referenced by the sproc then it recompiles.
create table mytable (i int identity)
insert mytable default values
go 100
create proc sp1 as select * from mytable where i = 17
go
exec sp1
If you look at the plan for this execution, it shows a table scan as expected.
create index mytablei on mytable(i)
exec sp1
The plan has changed to an index seek.
EDIT: ok I came up with a query that appears to work - this gives you all sproc names that have a reference to a given table in the plan cache. You can concatenate the sproc name with the sp_recompile syntax to generate a bunch of sp_recompile statements you can then execute.
;WITH XMLNAMESPACES (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
,TableRefs (SProcName, ReferencedTableName) as
(
select
object_name(qp.objectid) as SProcName,
objNodes.objNode.value('#Database', 'sysname') + '.' + objNodes.objNode.value('#Schema', 'sysname') + '.' + objNodes.objNode.value('#Table', 'sysname') as ReferencedTableName
from sys.dm_exec_cached_plans cp
outer apply sys.dm_exec_sql_text(cp.plan_handle) st
outer apply sys.dm_exec_query_plan(cp.plan_handle) as qp
outer apply qp.query_plan.nodes('//Object[#Table]') as objNodes(objNode)
where cp.cacheobjtype = 'Compiled Plan'
and cp.objtype = 'Proc'
)
select
*
from TableRefs
where SProcName is not null
and isnull(ReferencedTableName,'') = '[db].[schema].[table]'

I believe that the stored procedures that would potentially benefit from the presence of the index in question will automatically have a new query plan generated, provided the auto generate statistics option has been enabled.
See the section entitled Recompiling Execution Plans for details of what eventualities cause an automatic recompilation.
http://technet.microsoft.com/en-us/library/ms181055(SQL.90).aspx

Related

Does "With recompile" recompile all the queries in stored procedure?

So we have quite a large database and a stored procedure which searches through a large number of documents. Depending on the context, it either fetches millions of documents or just one hundred.
Point is, the procedure takes 30 seconds for both millions and hundred documents which is surreal. If I add OPTION (RECOMPILE) after each of the five queries, it takes a second for 100 documents and (expected) 30 seconds for millions of documents.
I've tried creating a procedure with WITH RECOMPILE option but it seems that it doesn't recompile queries in it.
Is this correct? Does the WITH RECOMPILE on stored procedure recompiles inner queries or just the execution plan for an entire SP? How can I do this without repeating OPTION (RECOMPILE) after each query?
Does the WITH RECOMPILE on stored procedure recompiles inner queries or just the execution plan for an entire SP?
inner queries or just execution plan,i am not sure what does this mean ? With Recompile at Stored proc level,will cause recompilation every time the proc is executed and query is not saved to Cache
How can I do this without repeating OPTION (RECOMPILE) after each query?
create proc usp_test
with Recompile
as
Begin
--code
End
Some More Details:
With Recompile will recompile a new plan for the entire stored proc ,everytime its run..
suppose ,you have below proc
create proc usp_test
as
Begin
select * from t1
go
select * from t2
End
adding recompile on top of stored proc,will cause SQLServer to recompile all the batches in Stored proc
Instead of recompiling,the total proc,if you know for sure ,which batch is causing issues,you can add Option(Recompile) like below
create proc usp_test
as
Begin
select * from t1 option(recompile)
select * from t2
End
doing this,you are avoiding unnecessary recompilation of other batches
Both OPTION(RECOMPILE) and WITH RECOMPILE will give you execution plans based on the parameters used each time, but only OPTION (RECOMPILE) allows "parameter embedding optimization" where the parameters are replaced with literal constants when its parsing the queries. This can allow the optimizer to make simplifications to the query.
I would find out which query is actually causing the performance issue and use OPTION(RECOMPILE) on that.

How is select * from table stored in database

I'm new to SQL sever. My stored procedure has below statement
insert into [destination_table]
select * from [source_table]
Both tables have same schema. New column is added to both the tables and column is not null.
In this case do I need to compile the stored procedure again.
In this case do I need to compile the stored procedure again.
There is a bit of misconception here. You don't have to recompile the procedure, SQL Server will do that for you whenever SQL Server thinks it is necessary.
In this case the plan will be evicted from the plan cache and replaced with a new plan automatically when the procedure is executed the next time after the changes to the structures.

Manual recompile stored procedure SQL Server

How can I recompile manually a stored procedure in SQL Server? Is just like a drop and create?
I know can do it with an option in the create statement (WITH RECOMPILE), and it will be recompiled every execution, and executing sp_recompile #procedureName, which will only recompile it the next time it executes, but how can I recompile it manually without these two approaches?
Stored Procedures are compiled when they are "first" executed. "First" meaning, they have no chached plan. All you can do is invalidate the cache. In SQL-Server, there is no way to force compilation other than calling it.
(BTW, this is unlike Oracle, where you may have gotten the idea from)
In our application, we maintain a script called "run_sample_statements.sql". This contains a number of representative queries and procedure calls to cause compilation and caching. We used that after maintenance and index-rebuilds to test/precache the system before we release it for the users again.
Well, one way to do it is to find the plan handle by querying
Select st.Plan_handle
from
sys.dm_exec_cached_plans
CROSS APPLY
sys.dm_exec_sql_text(plan_handle) st
WHERE text like '% your proc name %'
Then DBCC FREEPROCCACHE (plan_handle)
This method is effectively the same as sp_recompile.

Does the prepared SQL statements in a stored procedure make the performance better?

I know there have already been lots of question about stored procedure vs prepared SQL statements, but I want to find out something different - if the prepared statements inside a procedure contribute to the performance of this stored procedure, which means make it better.
I have this question because I was told following points when searching some introduction of these 2 skills.
Stored procedure will store and compile your series of statements in
db, which will reduce the overhead of transferring & compiling.
Prepare statements will be compiled and cached in db for multiple
access which lead to less overhead.
I am puzzled about these 'compile', 'store', and 'overhead' - a little bit abstract.
I use prepared statement to avoid re-parse if it will be called frequently.
However should I use prepared statements (to cache & compile) inside a procedure? Since my procedure would have already been stored and compiled in DB, prepare something inside seems meaningless. (compile what was compiled?)
edit with sample code:
Create or Replace procedure MY_PROCEDURE
Begin
//totally meaningless here?
declare sqlStmt varchar(300);
declare stmt statement;
set sqlStmt='update MY_TABLE set NY_COLUMN=? where NY_COLUMN=?';
prepare stmt from sqlStmt;
execute stmt using 2,1
execute stmt using 4,3
..............
END
Is the the above one better than below, since it only parse the statement once? Or same, because statements in procedure will have been pre-compiled.
Create or Replace procedure MY_PROCEDURE
Begin
update MY_TABLE set NY_COLUMN=2 where NY_COLUMN=1;
update MY_TABLE set NY_COLUMN=4 where NY_COLUMN=3;
..............
END
When you first run a stored procedure the database engine parses the procedure and works out the optimal query plan to use when executing it - it then stores this query plan so that every time you run the procedure it doesn't have to recalculate it.
You can see this youself in Management Studio. If you CREATE or ALTER the stored procedure in question, then open a new query and use:
SET STATISTICS TIME ON
In that same query window run the stored procedure. In the messages tab of the result the first message will be something like:
SQL Server parse and compile time:
CPU time = 1038 ms, elapsed time = 1058 ms.
This is the overhead, execute the query again and you will see that the parse and compile time is now 0.
When you prepare a statement in code you get to take advantage of the same benefit. If you query is 'SELECT * FROM table WHERE #var = '+$var, each time you run that query SQL Server has to parse it and calculate the optimal execution plan. If you use a prepared statement SELECT * FROM table WHERE ?, SQL Server will calculate the optimal execution plan the first time you run the prepared statement, and from then on it can reuse the execution plan as with a stored procedure. The same goes if the statement you are executing is 'EXEC dbo.myProc #var = '+$var, SQL Server would still have to parse this statement each time so a prepared statement should still be used.
You do not need to prepare statements that you write inside stored procedures because they are already compiled as shown above - they are prepared statements in themselves.
On thing you should be aware of when using stored procedure and prepared statements is parameter sniffing.
SQL Server calculates and stores the optimal execution plan for the first variables used, if you happen to execute the stored procedure with some unusual variable on the first run, the execution plan stored may be completely suboptimal for the sorts of variables you typically use.
If you find you can execute a stored procedure from Management Studio and it takes say 2 seconds to execute, but performing the same action in your application takes 20 seconds, it's probably as a result of parameter sniffing.
In DB2 actually the opposite may be true. Statements in an SQL routine are prepared when the routine is compiled. Dynamic SQL statements, as in your example, are prepared during the routine run time.
As a consequence, the preparation of dynamic statements will take into account the most current table and index statistics and other compilation environment settings, such as isolation level, while static statements will use the statistics that were in effect during the routine compilation or the latest bind.
If you want stable execution plans, use static SQL. If your statistics change frequently, you may want to use dynamic SQL (or make sure you rebind your routines' packages accordingly).
The same logic applies to Oracle PL/SQL routines, although the way to recompile static SQL differs -- you'll need to invalidate the corresponding routines.

SQL Server performance fast only when refresh the stored procedure

I can run a stored procedure multiple times and it wont hit it's cache: (1665ms is duration column)
But if I then alter the stored procedure changing nothing: (240ms is duration column)
Problem: how to get the stored procedure to always be fast (on the second and next calls)
With some digging I found that when I called the SP initially (after a reboot) with a NULL applicationID
exec [dbo].[usp_Tab32] #responsibleReviewerID=1135,#applicationID=NULL,#environment=1,#userUIStatus=0,#roleID=NULL
then with a more confined query:
exec [dbo].[usp_Tab32] #responsibleReviewerID=1135,#applicationID=1406,#environment=1,#userUIStatus=0,#roleID=NULL
This would be slow.
However if I hit the more confined query first, then both would be fast.
To clear down the database plan cache:
DECLARE #dbId INTEGER
SELECT #dbId = dbid FROM master.dbo.sysdatabases WHERE name = ‘myDatabase’
DBCC FLUSHPROCINDB (#dbId)
More detail here
All against SQL2012 Developer edition.
Create your stored procedure with RECOMPILE and recompile at Runtime
CREATE PROCEDURE yourprodecurename
WITH RECOMPILE
AS
--your code here
GO
then call it in this way:
EXEC yourprodecurename WITH RECOMPILE
This should give you the experience you want, because, when a procedure is compiled for the first time or recompiled, the procedures query plan is optimized for the current state of the database.
So this can improve the procedure’s processing performance.