有没有办法以编程方式执行包含实际执行计划的查询,并查看是否有任何索引建议

我有很多查询,我想在sql server management studio上使用Include Actual Execution Planfunction测试每个查询

但是,对于1m +查询,我不可能手动执行此操作

所以我想我可以通过编程(从c#)执行包含实际执行计划function,并查看SQL服务器是否建议任何索引

在此处输入图像描述

首先,在我进入如何获取代码中的实际执行计划并找到报告需要索引的那些之前,我建议您查看使用数据库引擎优化顾问(DTA) ,您可以提供所有的列表查询,它将处理它们,告诉您可能的索引,统计信息以及许多其他可以帮助您规划查询的事情。

比给它一个1m +查询列表更好的是,您可以从服务器获取正在运行的实际查询的跟踪,它将关注占用时间最多的查询。


要回答您的原始问题,您需要在连接开始时添加SET STATISTICS XML ON ,这将为您提供您显示的GUI所基于的XML数据。 ( 有关获取计划的更多信息,请参见此处 )。 执行此操作后,您的查询将返回一个额外的结果集,其中包含第一列第一行中计划的xml。

这是一个快速而肮脏的function。

 private static string GetXmlPlanForQuery(string queryText) { string result = null; using (var connection = new SqlConnection(connectionString)) using (var command = new SqlCommand()) { connection.Open(); command.Connection = connection; //Enable the statistics. command.CommandText = "SET STATISTICS XML ON"; command.ExecuteNonQuery(); //Run through the query, keeping the first row first column of the last result set. command.CommandText = queryText; using (var reader = command.ExecuteReader()) { object lastValue = null; do { if (reader.Read()) { lastValue = reader.GetValue(0); } } while (reader.NextResult()); if (lastValue != null) { result = lastValue as string; } } } return result; } 

这里是它为查询返回的XML, select TOTAL_SALES from clients where ACTIVE = 0; 我在我的一个本地数据库上运行了。

                                                              

现在,因为Microsoft非常好,如果您导航到XML中列出的命名空间,您实际上可以获得该格式的.xsd副本。 然后,您可以从开发人员的命令提示符下执行xsd showplanxml.xsd /classes ,它将为您提供可与XmlSerializer使用的showplanxml.cs

这是一个小例子程序,它对丢失的索引执行调试器中断。

 static void Main(string[] args) { string result = GetXmlPlanForQuery("select TOTAL_SALES from clients where ACTIVE = 0;"); XmlSerializer ser = new XmlSerializer(typeof(ShowPlanXML)); var plan = (ShowPlanXML)ser.Deserialize(new StringReader(result)); var missingIndexes = plan.BatchSequence.SelectMany(x => x) .SelectMany(x => x.Items) .OfType() .Select(x => x.QueryPlan) .Where(x => x.MissingIndexes != null && x.MissingIndexes.Any()); foreach (var queryPlan in missingIndexes) { //This will hit for each statement in the query that was missing a index, check queryPlan.MissingIndexes to see the indexes that are missing. Debugger.Break(); } Console.WriteLine("Done"); Console.ReadLine(); } 

我使用XmlSerializer并将其解析为类,但您可以轻松地将其加载到XDocument中,然后使用XPath查找名为MissingIndex所有节点。