c# - 通过 .NET 代码禁用 SQL Server 的缓存

标签 c# .net sql-server

我目前正在调用一些 .NET 代码中的几个存储过程,SqlConnection。我想禁用 SQL Server 完成的缓存,以便我可以定期测量性能(我将把它与另一台可能也没有任何缓存数据的服务器进行比较)。这是否可以在不修改存储过程的情况下完成?

这是我目前使用的代码:

using (SqlConnection connection = new SqlConnection(/* connection string goes here */)) {

    SqlCommand command = new SqlCommand(procName, connection);
    command.Parameters.AddRange(parameters);
    command.CommandType = System.Data.CommandType.StoredProcedure;
    connection.Open();

    SqlDataReader r = command.ExecuteReader();
    // todo: read data here
    r.Close();
    connection.Close();
}

最佳答案

首先,通过此处的“缓存”,我假设您指的是执行计划缓存。一旦 SQL Server 计算出执行语句的最佳顺序,它就会存储一段时间。这个问题通常被称为“参数嗅探”。这是您在运行 dbcc freeproccache 时清除的内容。不幸的是,这是一个具有管理员权限的命令,它会影响所有连接。

问题的根源在于您的 SQL 可能会因一组不同的参数而执行不同的操作。 SQL Server 只会存储它看到的第一次执行的执行计划和与之关联的参数。因此,如果第一次执行时的论点适用于常见情况,您的应用程序将执行良好。但有时,第一次执行时会使用错误的参数,导致整个应用程序性能不佳。

有很多方法可以优化您的 SQL 语句以减少这种影响,但这并不是完全可以避免的。

  1. 动态生成 SQL - 每次执行时生成查询计划都会对性能造成影响,但如果使用错误的执行计划导致查询永远不会返回,这可能是值得的。我建议这条路,虽然它更麻烦。我发现 SET STATISTICS TIME ON 和 SQL Profiler 有助于减少计划生成时间。最大的改进来自对表使用三部分命名 (owner.schema.table)。
  2. 使用查询提示为您的查询指定一组“好的”初始参数。
SELECT Col1, Col2
FROM dbo.MySchema.MyTab
WHERE Col1=@Parameter
OPTION (OPTIMIZE FOR (@Parameter='value'));

此链接描述了 parameter sniffing problem相当好。这在 SQL 2005 中是一个更大的问题。后来的 SQL 版本更好地避免了这个问题。

关于c# - 通过 .NET 代码禁用 SQL Server 的缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34912319/

相关文章:

c# - 如何在 XAML 中的网格单元格上拉伸(stretch)矩形

sql - min 和 max 不适用于位字段是否有任何原因

c# - 在构建更复杂的表达式时如何重用表达式?

C# 检查 ConsoleKeyInfo.KeyChar 是否为数字

c# - Entity Framework Linq Query to List - 使用时出错包含 : Only primitive types, 支持枚举类型和实体类型

.net - 使用 Javascript .NET 回发传递多个参数

sql-server - 用于图表的 SQL Server Management Studio 插件

SQL Server 存储过程连接字符串作为查询

c# - 启动多个 winform 后退出应用程序的方法?

.net - 如何在反序列化 JSON 字符串时忽略数组项