Search code examples
sql-serverlinked-server

Improve query performance when joining on a linked server table


Unfortunately as a temporary measure whilst we fix our datacentre I need to run the following cross server query, can anyone suggest how I can get the performance to increase...

as have to run this statement at the start of a cursor

SELECT t.SearchId, t.VisitSourceId, t.SiteDomainId, t.trpUTMid, t.FlightPlus, t.StartDate,
t.CountryId, t.ProvinceId, t.Locationid, t.PlaceId, t.EstabId, t.CheckInDate, 
t.CheckOutDate, t.Rooms, t.Room1Adults, t.Room1Children, t.Room2Adults, t.Room2Children, 
t.Room3Adults, t.Room3Children, tc.OutcomeDate, tc.OutcomeId, tc.HotelsFound, tc.Notes

FROM [MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl t
INNER JOIN TrackingAcomSearchesOutcome_tbl tc
ON t.trpUTMid = tc.trpUTMid
LEFT JOIN [YAZOO].[MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl tid
ON t.trpUTMid = tid.trpUTMid
WHERE tid.trpUTMid IS NULL

Solution

  • One possible option would be to get the remote table replicated to the local server. This would put all tables on the same server, enabling the optimizer to use statistics to generate the best plan. Since you are only using trpUTMid, you could just replicate that column.

    Another option would be to use temp tables. Same idea, get all tables on the same server:

    SELECT trpUTMid
    INTO #Yazoo_TrackingAcomSearches_tbl
    FROM [YAZOO].[MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl
    
    
    SELECT t.SearchId, t.VisitSourceId, t.SiteDomainId, t.trpUTMid, t.FlightPlus, t.StartDate,
    t.CountryId, t.ProvinceId, t.Locationid, t.PlaceId, t.EstabId, t.CheckInDate, 
    t.CheckOutDate, t.Rooms, t.Room1Adults, t.Room1Children, t.Room2Adults, t.Room2Children, 
    t.Room3Adults, t.Room3Children, tc.OutcomeDate, tc.OutcomeId, tc.HotelsFound, tc.Notes
    
    FROM [MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl t
    INNER JOIN TrackingAcomSearchesOutcome_tbl tc
    ON t.trpUTMid = tc.trpUTMid
    LEFT JOIN #Yazoo_TrackingAcomSearches_tbl tid
    ON t.trpUTMid = tid.trpUTMid
    WHERE tid.trpUTMid IS NULL
    

    You could also create an index on the temp table to improve performance.

    I'd also recommend checking for lack of existence rather than the old left join where null ( read this for more info ):

    SELECT trpUTMid
    INTO #Yazoo_TrackingAcomSearches_tbl
    FROM [YAZOO].[MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl
    
    
    SELECT t.SearchId, t.VisitSourceId, t.SiteDomainId, t.trpUTMid, t.FlightPlus, t.StartDate,
    t.CountryId, t.ProvinceId, t.Locationid, t.PlaceId, t.EstabId, t.CheckInDate, 
    t.CheckOutDate, t.Rooms, t.Room1Adults, t.Room1Children, t.Room2Adults, t.Room2Children, 
    t.Room3Adults, t.Room3Children, tc.OutcomeDate, tc.OutcomeId, tc.HotelsFound, tc.Notes
    
    FROM [MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl t
    INNER JOIN TrackingAcomSearchesOutcome_tbl tc
    ON t.trpUTMid = tc.trpUTMid
    WHERE NOT EXISTS (
        SELECT NULL 
        FROM #Yazoo_TrackingAcomSearches_tbl
        WHERE trpUTMid = t.trpUTMid
    )