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

Kev*_*ans 5 .net c# sql-server

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

这是我目前使用的代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

saa*_*arp 0

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

问题的根源在于您的 SQL 使用不同的参数集可能会产生不同的性能。SQL Server 将只存储它看到的第一次执行的执行计划以及与其关联的参数。因此,如果第一次执行时的参数适合常见情况,那么您的应用程序将表现良好。但有时,第一次执行时会使用错误的参数,整个应用程序可能会表现不佳。

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

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

该链接很好地描述了参数嗅探问题。这是 SQL 2005 中的一个更大的问题。后来的 SQL 版本在避免这个问题上做得更好。