I have a stored procedure which is contains a lot of query.
I Would like to execute the query plan only for a specific query.
EX:
select * from A
select * from B
--QUERY PLAN THIS
select * from C
--END OF QUERY PLAN
select * from D
Thanks a lot
You really can't do that. So you have to work around the problem by extracting that specific bit of SQL and building its execution plan by itself.
It may be that you're curious to see if the execution plan is affected when running in the context of the rest of the stored procedure. In that case you'll have to go ahead and generate a plan on the whole procedure and decipher what piece of it is the query you're concerned with.
You may also find SQL profiler helpful when trying to optimize/troubleshoot specific elements of complicated procedures.
Related
Our team has assigned a new task to me to look into the performance of a huge stored procedure. When I observe in the development environment with the proper data I have noticed that the procedure takes a considerable time to execute. In my scenario it took around 45 minutes. There are multiple INSERT/DELETE/UPDATE queries are used in the stored procedure. But I am unable to get which query is causing the issue. The data volume which is used in the queries are also pretty less.
How can I pinpoint to the exact query in the stored procedure
which is getting executed?
My Server version is SQL Server 2008 R2.
There are couple of ways to find out the query which is executing as part of a stored procedure. Learn more about DMVs and SQL Profiler. Both will give you an oversight to pinpoint the queries that are being used in a stored procedure.
In SQL Profiler, use the SP:StmtCompleted or SP:StmtStarting to include the statements inside the query. But I would advice not to go with the Profiler as it affects the system memory as well. Also it may give you unwanted additional information as well.
The best way is to use DMV (Dynamic Management Views). If you know the process id (SPID) use the below query to find out the query
The first query will give you the details about the stored procedures and the second will give you the exact query which is currently executing. Replace the SPID in the below query with the corresponding SPID of your process.
SELECT requests.session_id,
requests.status,
requests.command,
requests.statement_start_offset,
requests.statement_end_offset,
requests.total_elapsed_time,
details.text
FROM sys.dm_exec_requests requests
CROSS APPLY sys.dm_exec_sql_text (requests.sql_handle) details
WHERE requests.session_id = SPID
ORDER BY total_elapsed_time DESC
SELECT SUBSTRING(detail.text,
requests.statement_start_offset / 2,
(requests.statement_end_offset - requests.statement_start_offset) / 2)
FROM sys.dm_exec_requests requests
CROSS APPLY sys.dm_exec_sql_text (requests.sql_handle) detail
WHERE requests.session_id = SPID
Once you have done identifying the queries which is causing slowness, you can use Actual execution plan to identify the issues in the query.
Try this and please comment whether it is working for you.
I have some long running (a few hours) stored procedures which contain queries that goes to tables that contain millions of records in a distributed environment. These stored procedures take a date parameter and filters these tables according to that date parameter.
I've been thinking that because of the parameter sniffing feature of SQL Server, at the first time that my stored procedure gets called, the query execution plan will be cached according to that specific date and any future calls will use that exact plan. And I think that since creating an execution plan takes only a few seconds, why would I not use RECOMPILE option in my long running queries, right? Does it have any cons that I have missed?
if the query should run within your acceptable performance limits and you suspect parameter sniffing is the cause,i suggest you add recompile hint to the query..
Also if the query is part of stored proc,instead of recompiling the entire proc,you can also do a statement level recompilation like
create proc procname
(
#a int
)
as
select * from table where a=#a
option(recompile)
--no recompile here
select * from table t1
join
t2 on t1.id=t2.id
end
Also to remind ,recompiling query will cost you.But to quote from Paul White
There is a price to pay for the plan compilation on every execution, but the improved plan quality often repays this cost many times over.
Query store in 2016 helps you in tracking this issues and also stores plans for the queries over time..you will be able to see which are performing worse..
if you are not on 2016,William Durkin have developed open query store for versions (2008-2014) which works more or less the same and helps you in troubleshootng issues
Further reading:
Parameter Sniffing, Embedding, and the RECOMPILE Options
I'm running SQL Server 2014.
In the following code, I have a temp table (defined earlier in code) that is being filled from a stored procedure. Most of the parameters for the stored procedure are standard data types, but #GroupLayoutSpecifications is a table variable that accepts a small heap table that is joined to within the stored procedure.
INSERT #StandardizedResponses
EXEC rpt.usp_QueryBuilder_GatherStandardizedResponses
#Member, #OrgUnits, #Groups, #MeasureName,
#StartDate, #EndDate, #InstrumentTypeIDs,
#BackgroundDataIDs, #GroupLayoutSpecifications;
The problem I'm having the query engine isn't able to effectively estimate the number of rows that the stored procedure is likely to return. It is typical for it to estimate a return of something like 1 row, with an actual return of closer to 200k rows. I believe this is what is causing a tempdb spillover later in the plan.
Is it likely that it is the table-type parameter that is causing the query engine some grief? If so, how might I get around that?
Similarly, is there a way to hint to SQL Server that the following query will likely result in a larger than expected row count?
I've researched this quite a bit through things like MSDN, this site, SQL Authority, and others, and am hoping someone here can help me tune this.
If you need more information to supply a reasonable answer, just let me know what you might need.
Cheers,
Joe
I am developing a .NET program to retrieve execution plans of all stored procedures in a given database. I am going to parse these XML's at program side.
SET SHOWPLAN_XML ON and execute the procedure gives the plan. However, the problem is that all the parameters of the procedure needs to be passed.
Is there any way to retrieve execution plan without passing any parameters of the stored procedure, by giving the name of the procedure only?
Yes, you probably want to take a look at the plan cache - SQL Server caches all execution plans and allows you to take a look at them using DMVs. For example the following is a basic query which will list all cached query plans (as xml) along with their SQL text. On most database you will also need to add additional filtering clauses to filter the results down to just the plans you are interested in.
SELECT UseCounts, Cacheobjtype, Objtype, TEXT, query_plan
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
Note that these plans only include the estimated execution plan and won't contain the "actual" values (e.g. actual number of reads). Also you can't use this to get the query plan for an encrypted stored procedure.
See also How do I obtain a Query Execution Plan?, also Tools for visualising execution xml plans as HTML may be useful for the "parsing the XML" part.
I completed my project, there are many procedures used and now I got the job to find the mostly used procedure and there average execution time.
In this way I know what are the procedures I need to tune first?
It there any way to get procedure execution history for a particular database?
I believe you can use the sys.dm_exec_query_stats dynamic management view. There are two columns in this view called execution_count, and total_worker_time that will help you.
execution_count gives the total number of times the stored procedure in question was executed since the last time it was recompiled.
total_worker_time gives the total CPU time in milliseconds that was spent executing this stored procedure since the last time it was recompiled.
Here is an MSDN link:
http://msdn.microsoft.com/en-us/library/ms189741.aspx
You can use dm_exec_cached_plans to look for the stored procedures that have been compiled into query plans. The function dm_exec_query_plan can be used to retrieve the object id for a plan, which in turn can be translated into the procedure's name:
select object_name(qp.objectid)
, cp.usecounts
from sys.dm_exec_cached_plans cp
cross apply
sys.dm_exec_query_plan(cp.plan_handle) qp
where cp.objtype = 'Proc'
order by
cp.usecounts desc
I think you want to check SQL Server Profiler for this.
You can check the details in MSDN and other places as well.
But, before using it in production server, you need to keep in mind that:
Profiler adds too much overhead to production server. So, first check when your site has less no of hits, and go ahead.
This is what the SQL Server Profiler is for. With it you can keep track of query run count, execution time, etc.