4

我希望通过 C# 收集查询计划以改进开发。

我的方法是使用DbCommandSET SHOWPLAN_XML ON

但...

  • Non-parameterized query将集中返回查询计划。
  • Parameterized query不会返回任何东西!

SQL Server 2008 R2 和 LocalDB(2012) 都有同样的问题。

如何获得参数化查询的计划?

你知道为什么我的参数化查询是不可计划的吗?


[示例:重现步骤]</h1>

1. 创建表。

创建表香蕉 (
  BananaId int IDENTITY(100,1),
  标题 nvarchar(512),
);
去

改变表香蕉
    添加约束 Banana_PK PRIMARY KEY(BananaId);
去

2. 执行查询

  • 非参数化查询

    这将是退货计划:

    using (var conn = new SqlConnection( {Connection Strings} )) {
        conn.Open();
        DbCommand command = conn.CreateCommand();
    
        command.CommandText = "SET SHOWPLAN_XML ON;";
        command.CommandType = CommandType.Text;
        command.ExecuteNonQuery();
    
        command.CommandText = "SELECT BananaId, Title FROM Banana Where BananaId = 999";
        var plan = (string)command.ExecuteScalar();
    
        command.CommandText = "SET SHOWPLAN_XML OFF;";
        command.ExecuteNonQuery();
    
        Debug.WriteLine(plan); // <ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" ...
    }
    
  • 参数化查询

    这不是响应计划:

    using (var conn = new SqlConnection( {Connection Strings} )) {
        conn.Open();
        DbCommand command = conn.CreateCommand();
    
        command.CommandText = "SET SHOWPLAN_XML ON;";
        command.CommandType = CommandType.Text;
        command.ExecuteNonQuery();
    
        command.CommandText = "SELECT BananaId, Title FROM Banana Where BananaId = @BananaId";
        var parameter = command.CreateParameter();
        parameter.ParameterName = "@BananaId";
        parameter.Value = 999;
        command.Parameters.Add(parameter);
        var plan = (string)command.ExecuteScalar();
    
        command.CommandText = "SET SHOWPLAN_XML OFF;";
        command.ExecuteNonQuery();
    
        Debug.WriteLine(plan); // (null)
    }
    
4

2 回答 2

2

而不是创建 SqlParameters,而是创建一堆 T-SQL DECLARE 语句并为您的查询添加前缀。然后该计划将按预期工作。

DECLARE @BananaId INT
SELECT BananaId, Title FROM Banana Where BananaId = @BananaId
于 2017-01-26T20:05:21.020 回答
0

最后,我找到了可笑且有限的答案。
为什么丑?因为它必须执行SQL!

所以...我必须排除“NON SELECT”SQL 以避免重复的数据更改。

同时关注时我可以得到 QueryPlan。

  1. 利用SET STATISTICS XML ON(OFF)
  2. 利用ExecuteReader()
于 2015-02-17T06:48:13.493 回答