Stored-Procedures

在 ssms 中執行 sp 比在作業步驟中執行快得多

  • April 14, 2015

我的儲存過程在 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/。我不確定您正在執行什麼版本,但那裡也可能存在一些問題。

希望這可以幫助。

引用自:https://dba.stackexchange.com/questions/97443