在我们的应用程序中,我们有以下数据处理层:
- .NET 编排应用程序,确定要触发的 SSIS 包
- 完成大部分工作并调用存储过程的 SSIS 包
- 在 SSIS 数据流不合适的情况下执行计算和读/写数据的存储过程
如果从 SSMS 执行,一个存储过程将在 40 秒内运行,如果手动调用 SSIS 程序包,则运行时间大致相同。
但是,如果 .NET 应用程序调用 SSIS 包,则查询需要超过 14 小时才能运行,并使所有处理器保持一致。
查看执行计划,似乎如果程序是从 SSMS 运行的,或者手动触发 SSIS 包然后调用该程序,则 SQL Server 使用基于当前统计信息的合理计划。
但是,如果从 .NET 应用程序调用 SSIS 包,则 SQL 服务器会创建一个新计划,使用完全错误的统计信息。以下事情没有区别:
- 更新统计数据
- 清除缓存
- 重启实例
- 在程序执行时设置 WITH RECOMPILE
我们通过在查询中使用 MAXDOP 提示来篡改分辨率,但我的问题是:
当通过我描述的方法使用相同的参数和相同的数据调用时,是什么让 SQL Server 基于完全不正确的统计信息生成完全不同的计划?