Linked Server Insert-Select Performance

后端 未结 6 624
时光取名叫无心
时光取名叫无心 2021-01-02 17:30

Assume that I have a table on my local which is Local_Table and I have another server and another db and table, which is Remote_Table (table struct

6条回答
  •  抹茶落季
    2021-01-02 18:22

    The reason why it's so slow to insert into the remote table from the local table is because it inserts a row, checks that it inserted, and then inserts the next row, checks that it inserted, etc.

    Don't know if you figured this out or not, but here's how I solved this problem using linked servers.

    First, I have a LocalDB.dbo.Table with several columns:

    IDColumn (int, PK, Auto Increment)
    TextColumn (varchar(30))
    IntColumn (int)
    

    And I have a RemoteDB.dbo.Table that is almost the same:

    IDColumn (int)
    TextColumn (varchar(30))
    IntColumn (int)
    

    The main difference is that remote IDColumn isn't set up as as an ID column, so that I can do inserts into it.

    Then I set up a trigger on remote table that happens on Delete

    Create Trigger Table_Del
        On Table
        After Delete
    AS
    Begin
        Set NOCOUNT ON;
    
        Insert Into Table (IDColumn, TextColumn, IntColumn)
         Select IDColumn, TextColumn, IntColumn from MainServer.LocalDB.dbo.table L 
          Where not exists (Select * from Table R WHere L.IDColumn = R.IDColumn)
    
    END
    

    Then when I want to do an insert, I do it like this from the local server:

    Insert Into LocalDB.dbo.Table (TextColumn, IntColumn) Values ('textvalue', 123);
    Delete From RemoteServer.RemoteDB.dbo.Table Where IDColumn = 0;
    
    --And if I want to clean the table out and make sure it has all the most up to date data:
    Delete From RemoteServer.RemoteDB.dbo.Table
    

    By triggering the remote server to pull the data from the local server and then do the insert, I was able to turn a job that took 30 minutes to insert 1258 lines into a job that took 8 seconds to do the same insert.

    This does require a linked server connection on both sides, but after that's set up it works pretty good.

    Update:
    So in the last few years I've made some changes, and have moved away from the delete trigger as a way to sync the remote table.

    Instead I have a stored procedure on the remote server that has all the steps to pull the data from the local server:

    CREATE PROCEDURE [dbo].[UpdateTable]
        -- Add the parameters for the stored procedure here
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        -- Insert statements for procedure here
    
        --Fill Temp table
        Insert Into WebFileNamesTemp Select * From MAINSERVER.LocalDB.dbo.WebFileNames
    
        --Fill normal table from temp table
        Delete From WebFileNames
        Insert Into WebFileNames Select * From WebFileNamesTemp
    
        --empty temp table
        Delete From WebFileNamesTemp
    END
    

    And on the local server I have a scheduled job that does some processing on the local tables, and then triggers the update through the stored procedure:

    EXEC sp_serveroption @server='REMOTESERVER', @optname='rpc', @optvalue='true'
    EXEC sp_serveroption @server='REMOTESERVER', @optname='rpc out', @optvalue='true'
    EXEC REMOTESERVER.RemoteDB.dbo.UpdateTable
    EXEC sp_serveroption @server='REMOTESERVER', @optname='rpc', @optvalue='false'
    EXEC sp_serveroption @server='REMOTESERVER', @optname='rpc out', @optvalue='false'
    

提交回复
热议问题