我们有一个使用LINQ to SQL(ORM)的.NET应用程序来调用一个视图,该视图包含来自不同数据库中多个对象的连接。 .NET应用程序超时调用此视图,但是我们的DBA运行以下语句:
sp_refreshview on the view and the subsequennt sql views
应用程序再次开始运行。
此应用程序在接近20分钟后再次在同一视图上开始超时。因此,我们的DBA安排了一项工作,每30分钟运行一次上述声明。视图没有结构上的变化,我们试图弄清楚为什么sp_refreshview
修复了这个问题,以及我们可以解决的潜在问题是什么?
答案 0 :(得分:4)
sp_refreshview
解决问题的原因是视图不受架构限制。 SQLServer保留有关视图的元数据以帮助执行,并且由于视图不是模式绑定的,因此随着基础对象的更新,元数据会过时(想想DML语句)。 sp_refreshview
所做的是更新非架构绑定视图的元数据,以便它们可以以最佳方式运行。请查看sp_refreshview
的{{3}}。
为了澄清其原因,请考虑一下视图是什么?视图只是一个查询。存储的元数据与该查询相关。
每当您运行查询时,服务器都会找出运行该查询的最佳方式(称为计划),这取决于查询中使用的表的统计信息。随着表中的数据发生变化,表的统计信息将发生变化,因此计划可能会发生变化。创建视图(非模式绑定)时,会存储围绕最佳执行的元数据(很可能是计划)。由于视图只是一个查询,因此该计划可能会过时,sp_refreshview
会更新该元数据。
答案 1 :(得分:2)
最有可能sp_refreshview
导致服务器从缓存中删除查询的缓存执行计划。在调用sp_refreshview
后运行查询时,会生成新的(更好的)执行计划。这就是调用sp_refreshview
有帮助的原因。显然,更新统计信息并不会删除缓存的执行计划,这就是为什么它对您的情况没有帮助。
有些类型的查询无法对所有可能的参数值有一个好的计划,或者您的数据可能会严重偏差。
如果您在查询中添加OPTION(RECOMPILE)
,则很可能不需要致电sp_refreshview
以使其快速运行。
我不知道在ORM生成查询时如何添加此查询提示。
我建议你阅读Erland Sommarskog撰写的优秀文章Slow in the Application, Fast in SSMS。
答案 2 :(得分:0)
元数据是有关视图使用的表的信息。统计信息更新有关数据的信息。查看View定义可能会有所帮助。例如,在视图中选择*可能会导致问题。作为复习,视图只是一个声明,直到它被执行。如果您正在使用始终更改其结构或已删除并重新添加的表,则每次都需要运行sp_refreshview。如果您需要其他帮助,则需要提供查询以及基础表的任何信息,例如刷新它们的过程。所有上述评论都在合理范围内。