If I run this command in SSMS:
set showplan_xml on
GO
exec some_procedure 'arg1', 'arg2','arg3'
GO
set showplan_xml off
GO
I get XML output of the full call stack involved in the query execution, as well as any suggested indexes etc.
How might one read this from C#?
(One use case might be to periodically enable this and log these results in a production environment to keep an eye on index suggestions.)
To generate an actual execution plan you have to include the actual execution plan from the toolbar option as shown in the screen below. Now, you have to run your query and you can see in your result window there is an extra tab generated with the name "Execution plan" as shown below.
Showplan analysis You can sort the result in the difference, actual and estimated columns to find the problem and recommendations for the specific operator in the execution plan. This is available from SSMS 17.4. To do this, just right-click on the execution plan and then click on Analyze the Actual Execution Plan.
You can press Ctrl+L after writing the query in the Query window. In the Context Menu of the Query Window, you will find a menu on the toolbar in SQL Server Management Studio with the name “Display Estimated Execution Plan”. It will work the same way as the above step will do.
This is, for the most part, two separate (though related) questions.
If you want only the Suggested Indexes (and don't care about the rest of the execution plan), then you would probably be better off using the DMVs associated with missing indexes. You just need to write some queries instead of app code. Of course, DMV info is reset whenever the service restarts, but you can capture query results into a table if you want/need to keep a history. Please see the following MSDN pages for full details:
The only benefit that I can see to capturing the Execution Plan to get this info is that it would include the query text that resulted in the suggestion, which obviously is great for doing that research for determining which indexes to implement, but will also potentially explode the number of rows of data if many variations of a query or queries result in the same suggested index. Just something to keep in mind.
Yes, this is definitely doable and I have done it myself. You can do it in .NET whether it is a Console App, Windows Form, Web App, SQLCLR, etc.
Here are the details of what you need to know if you want to capture XML plans:
NVARCHAR
/ string
SET SHOWPLAN_XML ON;
SELECT 1
and DECLARE @Bob INT; SET @Bob = 52;
SET STATISTICS XML ON;
SELECT 1
and DECLARE @Bob INT; SET @Bob = 52;
NVARCHAR
, with a field name of Microsoft SQL Server 2005 XML Showplan (which has been consistent, at least up through SQL Server 2014; I haven't yet tested SQL Server 2016).BEGIN TRAN;
/ COMMIT TRAN;
so that no actual data modifications occur.SET
commands need to be in their own batch, so get plans via something like:
SqlConnection _Connection = new sqlConnection(_ConnectionStringFromSomewhere);
SqlCommand _Command = _Connection.CreateCommand();
SqlDataReader _Reader = null;
try
{
_Connection.Open();
// SET command needs to be in its own batch
_Command.CommandText = "SET something ON";
_Command.ExecuteNonQuery();
// Now we can run the desired query
_Command.CommandText = _QueryToTest;
_Reader = _Command.ExecuteReader();
..get you some execution plans!
}
finally
{
if (_Reader != null)
{
_Reader.Dispose();
}
_Command.Dispose();
_Connection.Dispose();
}
As a final note I will mention that for anyone interested in capturing execution plans but not interested in writing any code to get them, I have already implemented this as a SQLCLR stored procedure. The procedure gets not only the XML Execution Plan(s), but also the output from STATISTICS TIME
and STATISTICS IO
, both of which are harder to capture as they are returned as messages (just like PRINT
statements). And, the results of all 3 types of output can be captured into tables for further analysis across multiple executions (handy for doing A / B comparisons of current and revised code). This is available in the SQL# SQLCLR library (which again, I am the author of). Please note that while there is a Free version of SQL#, this particular stored procedure, DB_GetQueryInfo, is only available in the Full version, not the Free version.
UPDATE:
Interestingly enough, I just ran across the following MSDN article that describes how to use SQLCLR to grab the estimated plan, extract the estimated cost, pass it back as an OUTPUT parameter of the SQLCLR Stored Procedure, and then make a decision based on that. I don't think I would use it for such a purpose, but very interesting given that the article was written in 2005:
Processing XML Showplans Using SQLCLR in SQL Server 2005
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With