表A(要合并的表)有90,000行 表B(源表)有3,677行 我希望这个合并得非常快,但需要花费30分钟(并计算)。 如何优化以更快地运行?
ALTER PROCEDURE [dbo].[MergeAddressFromGraph]
-- no params
AS 开始 - 添加SET NOCOUNT ON以防止出现额外的结果集 - 干扰SELECT语句。 SET NOCOUNT ON;
-- first add fids to the MergeFundraiserNameAddress table instead of the temp table?
SELECT fundraiserid, ein
INTO #fids
FROM bb02_fundraiser
BEGIN TRAN;
MERGE BB02_FundraiserNameAddress AS T
USING
(
select f.fundraiserid,
n.addresslines,
n.town,
n.county,
n.postcode,
n.country,
n.fulladdress,
n.ein
from MergeFundraiserNameAddress n
join bb02_fundraiser f
on f.ein = n.ein and f.isdefault = 1
group by n.ein,
f.fundraiserid,
n.addresslines,
n.town,
n.county,
n.postcode,
n.country,
n.fulladdress
) AS S
ON (T.fundraiserid in( (select fundraiserid from #fids where ein = S.ein)) )
WHEN MATCHED
THEN UPDATE
SET
-- ADDRESS
T.addresslines = S.addresslines
,T.town = S.town
,T.county = S.county
,T.postcode = S.postcode
,T.country = S.country
,T.fulladdress = S.fulladdress
;
DELETE FROM MergeFundraiserNameAddress
COMMIT TRAN;
drop table #fids
END
更新 我能够改进现在只需几秒钟即可运行的存储过程。我加入了临时表而不是bb02_fundraiser表,并删除了ON子句中的子查询。
我现在意识到Merge不是必需的,我可以使用Update,但我现在对此很好,因为在重构中可能很快就需要INSERT。
以下更新的存储过程 IF OBJECT_ID('tempdb .. #fids')IS NOT NULL DROP TABLE #fids
SELECT fundraiserid, ein
INTO #fids
FROM bb02_fundraiser
where isdefault = 1
BEGIN TRAN;
MERGE BB02_FundraiserNameAddress AS T
USING
(
select f.fundraiserid,
n.addresslines,
n.town,
n.county,
n.postcode,
n.country,
n.fulladdress,
n.ein
from MergeFundraiserNameAddress n
join #fids f
on f.ein = n.ein
group by n.ein,
f.fundraiserid,
n.addresslines,
n.town,
n.county,
n.postcode,
n.country,
n.fulladdress
) AS S
ON (T.fundraiserid = S.fundraiserid)
WHEN MATCHED
THEN UPDATE
SET
-- ADDRESS
T.addresslines = S.addresslines
,T.town = S.town
,T.county = S.county
,T.postcode = S.postcode
,T.country = S.country
,T.fulladdress = S.fulladdress
;
DELETE FROM MergeFundraiserNameAddress
COMMIT TRAN;
IF OBJECT_ID('tempdb..#fids') IS NOT NULL
DROP TABLE #fids
答案 0 :(得分:0)
如果只有这份声明为你完成这项工作,请参见下文。
UPDATE T
SET T.addresslines = n.addresslines
,T.town = n.town
,T.county = n.county
,T.postcode = n.postcode
,T.country = n.country
,T.fulladdress = n.fulladdress
from MergeFundraiserNameAddress n join bb02_fundraiser f
on f.ein = n.ein and f.isdefault = 1
INNER JOIN BB02_FundraiserNameAddress T
ON T.fundraiserid = f.fundraiserid AND T.ein = f.ein
group by n.ein,
f.fundraiserid,
n.addresslines,
n.town,
n.county,
n.postcode,
n.country,
n.fulladdress
正如其他用户在您的评论中提到的,为什么在仅更新记录时使用MERGE语句。当您执行多个操作(如UPDATE,DELETE和INSERT)时,将使用MERGE语句。
由于您只是UPDATING记录,因此不需要merge语句。
效果不佳的原因
由于您获取Temp表中的所有记录,然后将其与其他表连接而不在该Temp表上创建任何索引,因此缺少任何索引都会损害查询性能。
当您执行SELECT * INTO #TempTable FROM Some_Table时,它会将Some_Table中的所有数据带入Temp表而不是索引。你可以通过运行这个简单的查询来看到自己
select * from tempdb.sys.indexes
where object_id = (select object_id
from tempdb.sys.objects
where name LIKE '#TempTable%')
答案 1 :(得分:0)
也可以在截断时删除原因。
截断表MergeFundraiserNameAddress