通过 .net sql 驱动程序和 Sql Management Studio 运行的查询截然不同

通过 .net sql 驱动程序和 Sql Management Studio 运行的查询截然不同

我们的应用程序使用.net sql驱动程序,查询最终在分析器中看起来像这样:

sp_executesql N'query where @param = ?, and param2 = ?', param, param2, param3, etc

将查询从 Profiler 复制并粘贴到 SQL Server Management Studio 中时,查询将在不到一分钟的时间内运行,而从应用程序执行则需要 15 到 20 分钟。

据我所知,他们都使用相同的执行计划,所以我不确定会有什么不同。

更奇怪的是,我们还有一个测试 SQL Server,它基本上是生产服务器的副本。在我们的测试环境中,使用相同的代码和大部分相同的数据(比生产时间晚了几天),查询在我们的应用程序以及 SQL Server Management Studio 中运行不到一分钟。再一次,探查器为它们全部捕获了完全相同的执行计划。

我发现唯一能让查询正确运行的方法是在数据库上运行 sp_updatestats,我们每天早上 5:00 运行它。奇怪的是到早上 7:00 查询仍然运行缓慢。如果我再次运行 sp_updatestats,查询将在不到一分钟的时间内完成。再次,所有执行计划看起来都一样。

我肯定漏掉了什么。有什么想法吗?

答案1

您的查询是否涉及具有升序 datetime 或 datetime2 列的表,并且其中一个参数是通常查找最近值的 datetime 或 datetime2?

您对更新统计数据后的行为的评论表明您遇到了 Gail Shaw 在此处描述的经常过时的统计数据问题:http://sqlserverpedia.com/blog/sql-server-bloggers/statistics-row-estimations-and-the-ascending-date-column/

正如 Gail 所说,最直接的解决办法是更频繁地更新统计数据。理想情况下,更频繁的更新只针对需要更新的统计数据——请参阅更新统计信息

对于非常大的表,过滤索引也可能有用,具体取决于表的大小以及更新和读取模式。

答案2

目前正在尝试升级我的 SQL 技能,所以对此持保留态度。但也许这是一个参数嗅探问题?:

参数嗅探是 SQL Server 使用首次执行存储过程时传递的调用参数为存储过程创建最佳计划的过程。所谓“首次”,实际上是指 SQL Server 被迫编译或重新编译存储过程,因为它不在过程缓存中。后续每次使用相同参数调用同一存储过程时,也会获得最佳计划,而使用不同参数值的调用可能并不总是获得最佳计划。

--http://www.simple-talk.com/sql/t-sql-programming/参数嗅探/

正如我在免责声明中所说的那样,我有很多东西需要学习,但如果我理解正确的话,如果是这种情况,我想如果你传递OPTION RECOMPILE给查询并且问题消失,这可能是你的问题。

相关内容