链接服务器的缓慢更新语句
Slow Update Statement with Linked Server
链接服务器指向同一实例上的数据库。链接服务器存在的原因是因为数据库位于实例的另一个可用性组中。
如果可用性组在同一节点上,则行为相同,并且更新运行超过 30 秒。
UPDATE LINK.database.dbo.TBL2
正如@GarethD 正确指出的那样,跨链接服务器加入是 pit of despair。
安全的方法是始终明确说明如何在链接服务器之间推送数据。您可以使用 SELECT 有效地从链接服务器中提取数据,并且可以使用 JSON 或 XML 将批量数据推送到链接服务器。所以我会尝试这样的事情(这里所有内容都在 TempDb 中,通过环回链接服务器访问,但你明白了):
use tempdb
drop table if exists TBL_Pick
drop table if exists TBL2
go
create table TBL2(RECNUM INT,[DATE] date, QTY int)
insert into TBL2(RECNUM, [DATE],QTY) values (1,'9/9/2021',0)
insert into TBL2(RECNUM, [DATE],QTY) values (2,'9/9/2021',0)
insert into TBL2(RECNUM, [DATE],QTY) values (3,'9/9/2021',0)
insert into TBL2(RECNUM, [DATE],QTY) values (4,'9/9/2021',0)
create table TBL_Pick(CompanyCode varchar(200), ID int, recnum int, PickQty int)
insert into TBL_Pick(CompanyCode,ID,recnum,PickQty) values ('99',999,1,2)
insert into TBL_Pick(CompanyCode,ID,recnum,PickQty) values ('99',999,2,3)
insert into TBL_Pick(CompanyCode,ID,recnum,PickQty) values ('99',999,3,5)
go
declare @pick nvarchar(max) =
(
SELECT RECNUM,PickQty
FROM TBL_Pick
WHERE CompanyCode = '99' AND ID = 999
for json path
)
select *
from openjson(@pick)
with
(
RECNUM int,
PickQty int
) p
exec LOOPBACK.tempdb.sys.sp_executesql N'
with q as
(
select t.Date, t.Qty, p.PickQty
from TBL2 t
join openjson(@pick)
with
(
RECNUM int,
PickQty int
) p
on p.RECNUM = t.RECNUM
where t.DATE = ''9/9/2021''
)
UPDATE q
SET Qty = PickQty',
N'@pick nvarchar(max)',
@pick = @pick;
go
select * from tbl2
您可能会尝试使用 远程加入 提示来试验您的查询。
另一种方法是也尝试相反的方法,即 运行 远程服务器上的查询与 [this] 服务器链接。
update l set
l.date = '9/9/2021',
l.qty = p.pickQty
from
tbl_pick p
inner remote join LINK.database.dbo.TBL2 l on l.recnum=p.recnum and p.CompanyCode='99' and p.Id=999
链接服务器指向同一实例上的数据库。链接服务器存在的原因是因为数据库位于实例的另一个可用性组中。
如果可用性组在同一节点上,则行为相同,并且更新运行超过 30 秒。
UPDATE LINK.database.dbo.TBL2
正如@GarethD 正确指出的那样,跨链接服务器加入是 pit of despair。
安全的方法是始终明确说明如何在链接服务器之间推送数据。您可以使用 SELECT 有效地从链接服务器中提取数据,并且可以使用 JSON 或 XML 将批量数据推送到链接服务器。所以我会尝试这样的事情(这里所有内容都在 TempDb 中,通过环回链接服务器访问,但你明白了):
use tempdb
drop table if exists TBL_Pick
drop table if exists TBL2
go
create table TBL2(RECNUM INT,[DATE] date, QTY int)
insert into TBL2(RECNUM, [DATE],QTY) values (1,'9/9/2021',0)
insert into TBL2(RECNUM, [DATE],QTY) values (2,'9/9/2021',0)
insert into TBL2(RECNUM, [DATE],QTY) values (3,'9/9/2021',0)
insert into TBL2(RECNUM, [DATE],QTY) values (4,'9/9/2021',0)
create table TBL_Pick(CompanyCode varchar(200), ID int, recnum int, PickQty int)
insert into TBL_Pick(CompanyCode,ID,recnum,PickQty) values ('99',999,1,2)
insert into TBL_Pick(CompanyCode,ID,recnum,PickQty) values ('99',999,2,3)
insert into TBL_Pick(CompanyCode,ID,recnum,PickQty) values ('99',999,3,5)
go
declare @pick nvarchar(max) =
(
SELECT RECNUM,PickQty
FROM TBL_Pick
WHERE CompanyCode = '99' AND ID = 999
for json path
)
select *
from openjson(@pick)
with
(
RECNUM int,
PickQty int
) p
exec LOOPBACK.tempdb.sys.sp_executesql N'
with q as
(
select t.Date, t.Qty, p.PickQty
from TBL2 t
join openjson(@pick)
with
(
RECNUM int,
PickQty int
) p
on p.RECNUM = t.RECNUM
where t.DATE = ''9/9/2021''
)
UPDATE q
SET Qty = PickQty',
N'@pick nvarchar(max)',
@pick = @pick;
go
select * from tbl2
您可能会尝试使用 远程加入 提示来试验您的查询。
另一种方法是也尝试相反的方法,即 运行 远程服务器上的查询与 [this] 服务器链接。
update l set
l.date = '9/9/2021',
l.qty = p.pickQty
from
tbl_pick p
inner remote join LINK.database.dbo.TBL2 l on l.recnum=p.recnum and p.CompanyCode='99' and p.Id=999