这完全取决于您如何真正执行查询;
想象以下查询:
SqlConnection myConnection = new SqlConnection("connection_string");
SqlCommand myCommand = new SqlCommand();
myCommand.Connection = myConnection;
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandTimeout = some_long_time;
myCommand.CommandText = "database_killing_procedure_lol";
myConnection.Open() //Connection's now open
myCommand.ExecuteNonQuery();
会发生两件事;一种是这种方法将排队,直到 command.ExecuteNonQuery() 完成。第二个是我们还将在方法执行期间从连接池中绑定一个连接。
如果我们超时会发生什么?好吧,抛出了一个异常 - 一个 Number 属性 = -2 的 SqlException。但是,请记住,在上面的代码中,没有异常管理,所以所发生的只是对象将超出范围,我们需要等待它们被释放。特别是,在这种情况发生之前,我们的连接是不可重用的。
这是首选以下模式的原因之一:
using(SqlConnection myConnection = new SqlConnection("connection_string"))
{
using(SqlCommand myCommand = new SqlCommand())
{
SqlCommand myCommand = new SqlCommand();
myCommand.Connection = myConnection;
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandTimeout = some_long_time;
myCommand.CommandText = "database_killing_procedure_lol";
myConnection.Open() //Connection's now open
myCommand.ExecuteNonQuery();
}
}
这意味着,一旦查询完成,无论是自然的(它运行到完成)还是通过异常(超时或其他),资源都会立即返还。
在您的具体问题中,有大量查询需要很长时间才能执行,原因有很多。在 Web 应用程序中,您可能有许多用户争夺有限数量的资源;内存,数据库连接,cpu时间等等。因此,将任何这些与昂贵的操作捆绑在一起会降低您的 Web 应用程序的响应能力和性能,或者限制您可以同时服务的用户数量。此外,如果数据库操作成本很高,您也可以占用您的数据库,从而进一步限制性能。
仅出于这个原因,尝试降低数据库查询的执行时间总是值得的。如果你不能,那么你将不得不小心你可以同时运行多少这些类型的查询。
编辑:
所以您实际上对 SQL Server 端发生的事情很感兴趣...答案是...这取决于! CommandTimeout 实际上是一个客户端事件-您的意思是,如果查询时间超过 n 秒,那么我不想再等待了。 SQL Server 被告知是这种情况,但它仍然需要处理当前正在执行的操作,因此实际上可能需要一些时间才能 SQL Server 完成查询。它会尝试对此进行优先排序,但仅此而已。
对于交易尤其如此;如果您正在运行包含在事务中的查询,并且您将其作为异常管理的一部分回滚,那么您必须等到回滚完成。
看到人们恐慌并开始针对运行查询的 SQL 进程 ID 发出 KILL 命令也很常见。如果命令正在运行事务,这通常是一个错误,但对于长时间运行的选择来说通常是可以的。
SQL Server 必须管理其状态以保持一致。客户端不再侦听的事实意味着您浪费了工作,但 SQL Server 仍然需要自行清理。
所以是的,ASP.Net 方面的事情会很好,因为它不在乎,但是 SQL Server 仍然必须完成它开始的工作,或者达到可以安全放弃该工作的程度,或者回滚已打开的任何交易的任何更改。
这显然会对数据库服务器的性能产生影响,具体取决于查询!
即使是事务之外的长时间运行的 SELECT 或 UPDATE 或 INSERT 也必须完成。 SQL Server 会尽快尝试并放弃它,但前提是这样做是安全的。显然,特别是对于 UPDATES 和 INSERT,它必须达到数据库仍然一致的程度。对于 SELECT,它会尝试尽快结束。