Can any body help me in understanding if the execution plan for functions cached in SQL server?
Any online resource for this?
The accepted answer is inaccurate / misleading, primarily due to the referenced quote being too vague with regards to the term "user-defined functions".
There are several different types of User-Defined Functions in Microsoft SQL Server, and they are treated differently:
Multi-statement TVFs:
These are treated like Stored Procedures. The query that executes them only shows the reference to their name, not to any of their definition. They show up in sys.dm_exec_cached_plans with a cacheobjtype of "Compiled Plan" and an objtype of "Proc". Any input parameter values are also stored with the plan, hence Multi-statement TVFs are subject to parameter-sniffing issues.
Inline TVFs (iTVFs):
These are treated like Views. The query that executes them incorporates their definition. They show up in sys.dm_exec_cached_plans with a cacheobjtype of "Parse Tree" and an objtype of "View". Input parameter values are not stored with the plan, hence Inline TVFs are not subject to parameter-sniffing issues.
Scalar UDFs:
These are treated like Stored Procedures. The query that executes them only shows the reference to their name, not to any of their definition. They show up in sys.dm_exec_cached_plans with a cacheobjtype of "Compiled Plan" and an objtype of "Proc". Any input parameter values are also stored with the plan, hence Scalar UDFs are subject to parameter-sniffing issues. Also, unlike the two types of TVFs noted above, but like regular Stored Procedures, you can force recompilation of the execution plan using the WITH RECOMPILE option when executing via EXEC[UTE] instead of SELECT or SET.
SQLCLR objects:
These are treated more like client / app code. The query that executes them only shows the reference to their name, not to any of their definition. They show up in sys.dm_exec_cached_plans with a cacheobjtype of "CLR Compiled Func" or "CLR Compiled Proc", and an objtype of "Proc". But, unlike Multi-statement TVFs and Scalar UDFs, they do not have a definition and so do not have an associated query plan. However, any adhoc queries (not stored procedure calls) that they execute show up in sys.dm_exec_cached_plans with a cacheobjtype of "Compiled Plan" and an objtype of "Prepared". Any of these adhoc queries, if parameterized, should be storing the initial input parameter values with the prepared plan, and would hence be subject to parameter-sniffing issues.
For more details on object caching, please see the MSDN page on Caching Mechanisms.
Yes they do go in the execution plan cache.
The sys.dm_exec_query_plan DMV will show a plan for given plan handle. Quote from there:
Query plans for various types of
Transact-SQL batches, such as ad hoc
batches, stored procedures, and
user-defined functions, are cached in
an area of memory called the plan
cache. Each cached query plan is
identified by a unique identifier
called a plan handle. You can specify
this plan handle with the
sys.dm_exec_query_plan dynamic
management view to retrieve the
execution plan for a particular
Transact-SQL query or batch.
Yes they are considered for caching.
http://msdn.microsoft.com/en-us/library/ms181055.aspx
Related
I have then following tracert about one query in my application:
As you can see, the query reads all registers in the table and the result is a big impact in time duration.
But when I try to execute the query directly the result is another... What is wrong?
You executed ANOTHER query from SSMS.
The query shown in profiler is part of stored procedure, and has 8 parameters.
What you've executed is a query with constants that has another execution plan as all the constants are known and estimation was done in base of these known values.
When your sp's statement was executed the plan was created for god-knows-what sniffed parameters and this plan is different from what you have in SSMS.
From the thikness of arrows in SSMS it's clear that you query does not do 7.954.449 reads.
If you want to see you actual execution plan in profiler you should select corresponding event (Showplan XML Statistics Profile ).
Yes, There are two different queries. The Axapta uses placeholders in common. Your query uses literal constants.
The forceLiterals hint in the query make the Axapta query similar to your SSMS sample. Default Axapta hint is forcePlaceholders.
Main goal of placeholders is optimize a massive stream of similar queries with different constants from multiple clients. Mainly due to the use of a query plans cache.
see also the injection warning for forceLiterals:
https://msdn.microsoft.com/en-us/library/aa861766.aspx
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 have a simple SELECT statement with a couple columns referenced in the WHERE clause. Normally I do these simple ones in the VB code (setup a Command object, set Command Type to text, set Command Text to the Select statement). However I'm seeing timeout problems. We've optimized just about everything we can with our tables, etc.
I'm wondering if there'd be a big performance hit just because I'm doing the query this way, versus creating a simple stored procedure with a couple params. I'm thinking maybe the inline code forces SQL to do extra work compiling, creating query plan, etc. which wouldn't occur if I used a stored procedure.
An example of the actual SQL being run:
SELECT TOP 1 * FROM MyTable WHERE Field1 = #Field1 ORDER BY ID DESC
A well formed "inline" or "ad-hoc" SQL query - if properly used with parameters - is just as good as a stored procedure.
But this is absolutely crucial: you must use properly parametrized queries! If you don't - if you concatenate together your SQL for each request - then you don't benefit from these points...
Just like with a stored procedure, upon first executing, a query execution plan must be found - and then that execution plan is cached in the plan cache - just like with a stored procedure.
That query plan is reused over and over again, if you call your inline parametrized SQL statement multiple times - and the "inline" SQL query plan is subject to the same cache eviction policies as the execution plan of a stored procedure.
Just from that point of view - if you really use properly parametrized queries - there's no performance benefit for a stored procedure.
Stored procedures have other benefits (like being a "security boundary" etc.), but just raw performance isn't one of their major plus points.
It is true that the db has to do the extra work you mention, but that should not result in a big performance hit (unless you are running the query very, very frequently..)
Use sql profiler to see what is actually getting sent to the server. Use activity monitor to see if there are other queries blocking yours.
Your query couldn't be simpler. Is Field1 indexed? As others have said, there is no performance hit associated with "ad-hoc" queries.
For where to put your queries, this is one of the oldest debates in tech. I would argue that your requests "belong" to your application. They will be versionned with your app, tested with your app and should disappear when your app disappears. Putting them anywhere other than in your app is walking into a world of pain. But for goodness sake, use .sql files, compiled as embedded resources.
Select statement which is part of form clause of any
another statement is called as inline query.
Cannot take parameters.
Not a database object
Procedure:
Can take paramters
Database object
can be used globally if same action needs to be performed.
I have been doing a lot of reading up on execution plans and the problems of dynamic parameters in stored procedures. I know the suggested solutions for this.
My question, though, is everything I have read indicated that SQL Server caches the execution plan for stored procedures. No mention is made of Table-value functions. I assume it does so for Views (out of interest).
Does it recompile each time a Table-value function is called?
When is it best to use a Table-value function as opposed to a stored procedure?
An inline table valued function (TVF) is like a macro: it's expanded into the outer query. It has no plan as such: the calling SQL has a plan.
A multi-statement TVF has a plan (will find a reference).
TVFs are useful where you want to vary the SELECT list for a parameterised input. Inline TVFs are expanded and the outer select/where will be considered by the optimiser. For multi-statement TVFs optimisation is not really possible because it must run to completion, then filter.
Personally, I'd use a stored proc over a multi-statement TVF. They are more flexible (eg hints, can change state, SET NOCOUNT ON, SET XACTABORT etc).
I have no objection to inline TVFs but don't tend to use them for client facing code because of the inability to use SET and change state.
I haven't verified this, but I take for granted that the execution plan for functions are also cached. I can't see a reason why that would not be possible.
The execution plan for views are however not cached. The query in the view will be part of the query that uses the view, so the execution plan can be cached for the query that uses the view, but not for the view itself.
The use of functions versus stored procedured depends on what result you need from it. A table-valued function can return a single result, while a stored procedure can return one result, many results, or no result at all.
I'm trying to use SQL Server Profiler (2005) to track down some application performance problems. One of the calls being made is to a table-valued user-defined function. This function wraps a select that joins several tables together.
In SQL Server Profiler, the call to the UDF is logged. However, the select that underlies the UDF isn't being logged at all. Because of this, I'm not getting useful data on which tables & indexes are being hit. I'd like to feed this info into the Database Tuning Advisor for some indexing advice.
Is there any way (short of unwrapping the queries themselves) to log the tables called by UDFs in Profiler?
You can't: a multi-statement TVF is a black box and you can only get CPU, Read, Writes etc.
by "black box" I mean it's a fully encapsulated and opaque series of statements inside another query, and there is no "flow" like you'd get line by line through a stored proc.
An in-line TVF is expanded like a view or macro into the main query and can be seen.
Edit: related: Table Valued Function where did my query plan go?