我看到了经典的“在工作室管理器中运行速度快但在应用程序中运行缓慢”的问题。听起来可能是参数嗅探。但是,我在 ETL 和 SSIS 方面的经验为零。
从 DBA 我收到了以下查询,它以 ? 而不是一个参数。这是查询的混淆示例:
SELECT
tablex.x_id,
tablex.create_ts,
tablex.update_ts,
tablex.myStatus,
tablex.x_type,
tablex.ami_uploaded,
tablex.work_id,
tablex_capture_ts,
[column1],
[column2],
[column3],
[column4]
FROM sqltable..tablex
INNER JOIN
sqltable..tableWork ON tablex.work_id = tableWork.work_id
WHERE
(tablex.update_ts >= ?)
- 根据 DBA,问号被替换为过去一小时的“时间/日期”参数。
- 当我从存储过程在本地执行相同的查询时,传入一个过去一小时的参数,它会在不到一秒的时间内返回。(对我来说,这意味着它“可以”使用现有索引)
- 从 ETL 看这个执行,它需要几分钟,执行计划显示表扫描。
- 有一个 update_ts 索引。
查询引擎推荐第二个包含多个包含列的 update_ts 索引。如果可能的话,我想避免这种情况,因为它会增加内存压力,而且我不相信它可以解决真正的问题。想法?
这似乎是查询统计信息出现偏差的情况,当查询引擎嗅探参数时,它会避免使用现有索引,因为估计的行数超出了阈值。
我的问题:
- 怎么样?在 SSIS 查询中得到由 sql server 处理吗?我知道参数嗅探是一个复杂的问题。我一直在研究这个: http: //www.sommarskog.se/query-plan-mysteries.html
- 如果是查询引擎嗅探参数(过去一小时)并认为估计的行数超出了触发点,我该怎么做才能解决这个问题?DBA 拒绝了 OPTIMIZE for RECOMPILE 作为选项的提示,我不能说我不同意。(他有关于错误历史的观点)但是,这些查询仅在计划时间从 ETL 发生,也许这足以有理由使用提示而不管潜在的错误?
此外,这是我一直在努力解决的一个长期问题。所有这些帖子都与同一问题有关。多么奇妙的发现之旅:
SQL Server - 我可以手术删除一个糟糕的缓存查询计划还是我追求错误的想法?
任何意见是极大的赞赏。
这应该是本地存储过程版本的实际执行计划。此版本在 1 秒内返回,并表现出我希望 ETL 具有的行为:
https://www.brentozar.com/pastetheplan/?id=ry4wy6dBO
现在,这是 ETL 版本的屏幕截图,需要几分钟才能完成。抱歉,我无法提供有关此特定查询的更多详细信息:
这是一个小时内完成的分析器跟踪的屏幕截图。我认为这就是 ETL 命令的执行方式。我还不知道,为什么这些都有相同的时间。我还需要找到准备工作。看看那些 cpu、reads 和 duration 列!
我们在从 EntityFramework 调用的查询中遇到了类似的问题。在 SSMS 中速度很快,但在应用程序中速度很慢。
事实证明,参数映射及其类型存在错误,导致来自应用程序的查询进行扫描,因为查询变得非 SARGable。
修复此问题后,应用程序的查询速度很快。
我想分享一些与这个长期传奇相关的发现和成功故事。
如果您花时间学习 SSIS 和 ETL 可以做到的事情,真是太棒了。
事实证明,OPTION (RECOMPILE) 已经暴力破解了这个问题,过去需要 4 分钟的查询,现在需要 800 毫秒。
从 SSIS 生态系统之外的源数据库中获取数据的黑客也经过深思熟虑......消失了!
拥有城堡的钥匙并花时间学习系统是值得的。
举个有趣的例子……其中一个系统总共花了 18 分钟(完整的 ETL)来进行 30 分钟的窗口提取。
现在我们可以做一个 15 分钟的窗口,一切都需要 90 秒。提取变换和加载!
那么这个故事的寓意呢?花时间学习 SSIS。花时间调整系统。