SQL Server 2014 远程插入速度慢
SQL Server 2014 slow remote insert
我有几个链接服务器,我想在每个链接服务器中插入一个值。第一次尝试执行时,我等待 INSERT
使用 CURSOR
的时间太长了。它完成了大约 17 个小时。但我对那些 INSERT
查询很好奇,我使用 Display Estimated Execution Plan
检查了 INSERT
查询的一行,它显示 Remote Insert
和 [ 的成本为 46% =18=] 占 54%.
下面是我之前工作的代码片段
DECLARE @Linked_Servers varchar(100)
DECLARE CSR_STAGGING CURSOR FOR
SELECT [Linked_Servers]
FROM MyTable_Contain_Lists_of_Linked_Server
OPEN CSR_STAGGING
FETCH NEXT FROM CSR_STAGGING INTO @Linked_Servers
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
EXEC('
INSERT INTO ['+@Linked_Servers+'].[DB].[Schema].[Table] VALUES (''bla'',''bla'',''bla'')
')
END TRY
BEGIN CATCH
DECLARE @ERRORMSG as varchar(8000)
SET @ERRORMSG = ERROR_MESSAGE()
END CATCH
FETCH NEXT FROM CSR_STAGGING INTO @Linked_Servers
END
CLOSE CSR_STAGGING
DEALLOCATE CSR_STAGGING
下面还有我如何检查我的查询估计执行计划的图
我只检查 INSERT
个查询,而不是所有查询。
如何使用远程插入获得最佳实践和最佳性能?
你可以试试这个,但我认为差异应该可以忽略不计更好。我确实记得,当阅读跨链接服务器进行插入的方法的差异时,大多数标准方法基本上彼此相提并论,尽管我已经有一段时间没有查过了,所以不要引用我的话。
由于方法上的明显差异,它还需要您进行一些简单的重写(并假设您无论如何都能这样做)。执行此操作所需的动态 sql 可能很棘手,因为我不完全确定您是否可以在动态 sql 中调用 openquery(我应该知道这一点,但我从来不需要)。
但是,如果您可以使用这种方法,主要好处是 where 子句无需 select 任何数据即可获取目标模式(因为 1 永远不会等于 0)。
INSERT OPENQUERY (
[your-server-name],
'SELECT
somecolumn
, another column
FROM destinationTable
WHERE 1=0'
-- this will help reduce the scan as it will
-- get schema details without having to select data
)
SELECT
somecolumn
, another column
FROM sourceTable
您可以采用的另一种方法是在目标 server/DB 上构建一个插入过程。然后你只需通过发送参数来调用 proc。虽然是的,这需要做更多的工作,并且引入了更多需要维护的对象,但它会简化您的流程,并可能减少 I/O 跨链接服务器发送内容的时间,更不用说可能会节省 CPU您不断扫描的成本也是如此。我认为这可能是一种更简洁的方法,而不是试图优化链接服务器的行为。
我有几个链接服务器,我想在每个链接服务器中插入一个值。第一次尝试执行时,我等待 INSERT
使用 CURSOR
的时间太长了。它完成了大约 17 个小时。但我对那些 INSERT
查询很好奇,我使用 Display Estimated Execution Plan
检查了 INSERT
查询的一行,它显示 Remote Insert
和 [ 的成本为 46% =18=] 占 54%.
下面是我之前工作的代码片段
DECLARE @Linked_Servers varchar(100)
DECLARE CSR_STAGGING CURSOR FOR
SELECT [Linked_Servers]
FROM MyTable_Contain_Lists_of_Linked_Server
OPEN CSR_STAGGING
FETCH NEXT FROM CSR_STAGGING INTO @Linked_Servers
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
EXEC('
INSERT INTO ['+@Linked_Servers+'].[DB].[Schema].[Table] VALUES (''bla'',''bla'',''bla'')
')
END TRY
BEGIN CATCH
DECLARE @ERRORMSG as varchar(8000)
SET @ERRORMSG = ERROR_MESSAGE()
END CATCH
FETCH NEXT FROM CSR_STAGGING INTO @Linked_Servers
END
CLOSE CSR_STAGGING
DEALLOCATE CSR_STAGGING
下面还有我如何检查我的查询估计执行计划的图
我只检查 INSERT
个查询,而不是所有查询。
如何使用远程插入获得最佳实践和最佳性能?
你可以试试这个,但我认为差异应该可以忽略不计更好。我确实记得,当阅读跨链接服务器进行插入的方法的差异时,大多数标准方法基本上彼此相提并论,尽管我已经有一段时间没有查过了,所以不要引用我的话。
由于方法上的明显差异,它还需要您进行一些简单的重写(并假设您无论如何都能这样做)。执行此操作所需的动态 sql 可能很棘手,因为我不完全确定您是否可以在动态 sql 中调用 openquery(我应该知道这一点,但我从来不需要)。
但是,如果您可以使用这种方法,主要好处是 where 子句无需 select 任何数据即可获取目标模式(因为 1 永远不会等于 0)。
INSERT OPENQUERY (
[your-server-name],
'SELECT
somecolumn
, another column
FROM destinationTable
WHERE 1=0'
-- this will help reduce the scan as it will
-- get schema details without having to select data
)
SELECT
somecolumn
, another column
FROM sourceTable
您可以采用的另一种方法是在目标 server/DB 上构建一个插入过程。然后你只需通过发送参数来调用 proc。虽然是的,这需要做更多的工作,并且引入了更多需要维护的对象,但它会简化您的流程,并可能减少 I/O 跨链接服务器发送内容的时间,更不用说可能会节省 CPU您不断扫描的成本也是如此。我认为这可能是一种更简洁的方法,而不是试图优化链接服务器的行为。