4

我们有一个查询在我们的生产系统上大约需要 5 秒,但在我们的镜像系统(尽可能与生产系统相同)和开发系统上需要不到 1 秒。

我们检查了查询计划,我们可以看到它们不同。同样从这些计划中,我们可以看到为什么一个比另一个花费更长的时间。数据、架构和服务器相似,存储过程相同。

我们知道如何通过重新安排连接和添加提示来修复它,但是目前如果我们不必对 SProc(文书工作)进行任何更改,这会更容易。我们也尝试过 sp_recompile。

什么可能导致两个查询计划之间的差异?

系统:Win2k3 Enterprise 上的 SQL 2005 SP2 Enterprise

更新:感谢您的回复,原来是统计数据。请参阅下面的摘要。

4

6 回答 6

12

您的统计数据很可能已过时。如果您的数据相同,请重新计算两台服务器上的统计信息并重新编译。然后,您应该会看到相同的查询计划。

此外,请仔细检查您的索引是否相同。

于 2009-02-03T04:32:31.637 回答
3

您的镜像和生产之间的数据和数据大小是否尽可能接近相同?如果您知道为什么一个查询比另一个查询花费更长的时间?你能发布更多细节吗?

由于表中的数据和/或统计信息,在这种情况下执行计划可能会有所不同。即使在启用自动更新统计信息的情况下,统计信息也可能会过时(尤其是在非常大的表中)。您可能会发现优化器估计表不是那么大,并选择了表扫描或类似的方法。

于 2009-02-03T04:36:37.290 回答
3

最有可能的统计数据。

一些想法:您是否对非产品系统进行维护?(例如 rebuidl 索引,它将重建统计信息)

如果是这样,您是否使用相同的填充因子和统计采样率?

您是否定期将数据库恢复到测试中,使其 100% 像生产环境一样?

于 2009-02-03T04:48:51.760 回答
2

如果您的 proc 上没有 WITH RECOMPILE 选项,则执行计划将在第一次执行后被缓存。

这是一个关于如何缓存错误查询计划的简单示例:

create proc spTest
    @id int 
as 
select * from sysobjects where @id is null or id = id 

go 

exec spTest null
-- As expected its a clustered index scan

go

exec spTest 1
-- OH no its a clustered index scan 

尝试在存储过程之外的生产服务器上的 QA 中运行 Sql,以确定您的统计信息是否过时或生产中缺少神秘索引。

于 2009-02-03T04:49:07.140 回答
2

与第一个答案有关,问题可能出在 SQL Server 的参数嗅探功能上。它使用导致编译的第一个值来帮助创建执行计划。通常这是好的,但如果值不正常(或奇怪),它可能会导致一个糟糕的计划。这也可以解释生产和测试之间的区别。

关闭参数嗅探需要修改我理解的 SProc 是不可取的。但是,在使用 sp_recompile 之后,传入您认为“正常”的参数,它应该根据这些新参数重新编译。

我认为参数嗅探行为在 2005 年和 2008 年之间是不同的,所以这可能行不通。

于 2009-02-03T04:49:29.357 回答
0

解决方案是重新计算统计数据。我忽略了我们通常安排的任务来完成所有这些,但由于某种原因,管理员没有在这个服务器上放置一个,Doh。

总结所有帖子:

  • 检查设置是否相同
    • 索引
    • 桌子尺寸
    • 恢复数据库
  • 执行计划缓存
    • 如果查询在 SProc 之外运行相同,则不是执行计划
    • sp_recompile 如果不同
    • 参数嗅探
  • 重新计算统计
于 2009-02-03T05:25:58.033 回答