為什麼通過 SSIS 在 ETL 中的查詢很慢,但通過本地儲存過程卻很快?
我看到了經典的“在工作室管理器中執行速度快但在應用程序中執行緩慢”的問題。聽起來可能是參數嗅探。但是,我在 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。花時間調整系統。