Stored-Procedures
在 ssms 中執行 sp 比在作業步驟中執行快得多
我的儲存過程在 ssms 中需要 23 秒,但在通過作業執行時需要 4 分鐘。你能幫我找出答案嗎?下面是SP程式碼
ALTER procedure [ops].[trailers_sitting_builder_mod] --WITH RECOMPILE as SET NOCOUNT ON; INSERT INTO [ops].[trailers_sitting_mod] ([trailer_number] ,[division] ,[trailer_year] ,[trailer_make] ,[vin] ,[license_plate] ,[trailer_type] ,[trailer_status] ,[last_contact_customer] ,[last_contact_city] ,[last_contact_state] ,[last_contact_date] ,[last_gps_utc_datetime] ,[last_gps_mst_datetime] ,[last_gps_latitude] ,[last_gps_longitude] ,[last_gps_geotype] ,[last_gps_geoname] ,[last_gps_state] ,[last_gps_country] ,[last_gps_point_distance] ,[last_gps_point_direction] ,[last_gps_area] ,[last_gps_area_planner] ,[last_battery_status] ,[idle_duration_days] ,[idle_exception] ,[gps_not_reporting] ,[icc_gps_difference] ,[report_last_ran]) SELECT ltrim(rtrim(tm.TRTRLR)), tm.TRDV#, tm.TRYEAR, tm.TRMAKE, tm.TRSER, tm.TRMNPR, tm.TRTYPE, tm.TRTRST, tm.TRCUST, c.city_name, tm.TRCST, dd.Date_Value, mt.last_gps_datetime, dateadd(hh, -7, mt.last_gps_datetime), sb.sb_latitude, sb.sb_longitude, sb.sb_geotypename, sb.sb_geoname, sb.sb_state, sb.sb_country, sb.sb_distance, sb.sb_direction, sb.sb_areanum, p.planner_name, sb.sb_battery, sb.sb_idleduration, case when mt.last_gps_datetime is null or datediff(dd, mt.last_gps_datetime, getdate()) > 7 or sb.sb_idleduration > 7 then 1 else 0 end, --as idle_exception, case when mt.last_gps_datetime is null or datediff(dd, mt.last_gps_datetime, getdate()) > 7 then 1 else 0 end, --as gps_not_reporting, case when sb.sb_state <> tm.TRCST and mt.last_gps_datetime is not null and datediff(dd, mt.last_gps_datetime, getdate()) <= 7 then 1 else 0 end, --as icc_gps_difference, getdate() as report_last_ran from MVT520.MVT520.IESSHARE.TRAILERS tm left join ( select date_value, julian_day from BIWHSReports.dw_pub.dbo.tbl_Dim_Date ) dd on tm.TRCDAT = dd.Julian_Day left join ( select city_code, state, city_name from BIWHSReports.dw_pub.ops.tbl_Dim_ICC_city where etl_current_row = 1 ) c on tm.TRCCTY = c.city_code and tm.TRCST = c.state left join ( select sb_assetid, max(sb_time) as last_gps_datetime from BIWHSReports.DS_Raw.ops3rdParty.tblSkyBitz group by sb_assetid ) mt on ltrim(rtrim(tm.TRTRLR)) = mt.sb_assetid left join BIWHSReports.DS_Raw.ops3rdParty.tblSkyBitz sb on mt.sb_assetid = sb.sb_assetid and mt.last_gps_datetime = sb.sb_time left join ( select area_code, planner_name from BIWHSReports.dw_pub.ops.tbl_dim_icc_area where etl_current_row = 1 ) p on sb.sb_areanum = p.area_code where TRDLT <> 'D' --OPTION (RECOMPILE) GO --EXEC ops.trailers_sitting_builder
Profiler 中的許多計劃選項都是估計計劃,因此您必須使用正確的選項才能獲得實際計劃。由於您使用的是 SQL Sentry(順便說一句,這是一個很棒的產品:)),如果您在作業執行後不久進行檢查,您應該能夠從 Top SQL 選項卡中獲取執行語句的計劃。
無論如何,如果可能的話,我建議不要在主查詢中執行跨伺服器查詢,而是先將該數據拉入臨時表(假設它不是大量行),以便優化器具有“更容易”生成準確計劃的時間。此外,您共享的查詢相對複雜。我意識到還有更糟糕的事情,但我始終牢記的一個目標是不要讓優化器做太多事情。因此,“KISS”(保持簡單愚蠢)方法在應用於編寫查詢時通常會很有幫助。幫助優化器,你就幫助自己。考慮到這一點,我可能會建議您消除連接中的子查詢並製作這些臨時表,再次假設您沒有查看大量行。與性能調整中的所有內容一樣,嘗試、測試、
最後一點,最好閱讀 Joe Sack 的這篇文章 - http://www.sqlskills.com/blogs/joe/distributed-query-plan-quality-and-sql-server-2012-sp1/。我不確定您正在執行什麼版本,但那裡也可能存在一些問題。
希望這可以幫助。