环境:Visual Studio 2017,SQL Server 2016
今天遇到一个情况,一直跑得好好的代码,突然就跑不了啦,说执行超时,然后执行的SQL拿到数据库跑得还挺快。
错误提示如下
System.Data.SqlClient.SqlException (0x80131904): 执行超时已过期。完成操作之前已超时或服务器未响应。
后来看到有人说执行下面这个存储过程就好了,抱着死马当活马医的心态试一下,还真行。。。
感谢那位老哥。
exec sp_updatestats;
MSDN 对 sp_updatestats 的解释
sp_updatestats
UPDATE STATISTICS
通过ALL
在数据库中的所有用户定义表和内部表中指定关键字,sp_updatestats 执行。 sp_updatestats 显示指示其进度的消息。 完成更新之后,此存储过程将报告已为所有的表更新了统计信息。sp_updatestats 更新已禁用的非聚集索引的统计信息,并且不更新已禁用聚集索引的统计信息。
对于基于磁盘的表, sp_updatestats根据dm_db_stats_properties sys.databases目录视图中的modification_counter信息更新统计信息,并更新至少包含一行的统计信息。 Sp_updatestats执行时,将始终更新内存优化表的统计信息。 因此, sp_updatestats 不需要执行更多的操作。
sp_updatestats 可以触发存储过程或其他已编译代码的重新编译。 但是,如果在引用的表和索引上只有一个查询计划,则 sp_updatestats 可能不会导致重新编译。 在这些情况下,即便更新了统计信息也不必进行重新编译。
这里面又涉及一个 统计信息 的概念
查询优化的统计信息是二进制大型对象 (BLOB),这些对象包含与值在表或索引视图的一列或多列中的分布有关的统计信息。 查询优化器使用这些统计信息来估计查询结果中的基数或行数。 通过这些基数估计,查询优化器可以创建高质量的查询计划。 例如,查询优化器可以根据谓词使用基数估计选择索引查找运算符而不是更耗资源的索引扫描运算符,假如这样做能提高查询性能。
每个统计信息对象都在包含一个或对个表列的列表上创建,并且包括将值的分布显示在第一列的直方图。 在多列上的统计信息对象也存储与各列中的值的相关性有关的统计信息。 这些相关性统计信息(或 密度)根据列值的不同行的数目派生。