我有一個包含EntityID列的約200,000條記錄的列表,我將其加載到一個臨時表變量中。SQL Server - 使用NOT EXISTS的替代方案
如果Temp表中的EntityID不存在於dbo.EntityRows表中,我想從Temp表變量中插入任何記錄。 dbo.EntityRows表包含大約800,000條記錄。
與dbo.EntityRows表具有大約500,000條記錄相比,此過程非常緩慢。
我的第一個猜測是因爲NOT EXISTS子句,來自Temp變量的每一行都必須掃描dbo.EntityRows表的整個800k行以確定它是否存在。
問題:是否有其他方法可以在不使用NOT EXISTS的情況下運行此比較檢查,這會產生沉重的成本,並且只會隨着dbo.EntityRows的持續增長而變得更糟?
編輯:欣賞意見。這裏是查詢(我在IF NOT EXISTS檢查後省略了部分,之後如果不存在,我插入4個表格中)。
declare @EntityCount int, @Counter int, @ExistsCounter int, @AddedCounter int
declare @LogID int
declare @YdataInsertedEntityID int, @YdataSearchParametersID int
declare @CurrentEntityID int
declare @CurrentName nvarchar(80)
declare @CurrentSearchParametersID int, @CurrentSearchParametersIDAlreadyDone int
declare @Entities table
(
Id int identity,
EntityID int,
NameID nvarchar(80),
SearchParametersID int
)
insert into @Entities
select EntityID, NameID, SearchParametersID from YdataArvixe.dbo.Entity order by entityid;
set @EntityCount = (select count(*) from @Entities);
set @Counter = 1;
set @LogID = null;
set @ExistsCounter = 0;
set @AddedCounter = 0;
set @CurrentSearchParametersIDAlreadyDone = -1;
While (@EntityCount >= @Counter)
begin
set @CurrentEntityID = (select EntityID from @Entities
where id = @Counter)
set @CurrentName = (select nameid from @Entities
where id = @Counter);
set @CurrentSearchParametersID = (select SearchParametersID from @Entities
where id = @Counter)
if not exists (select 1 from ydata.dbo.entity
where NameID = @CurrentName)
begin
-- I insert into 4 tables IF NOT EXISTS = true
end
通常,['NOT EXISTS'是最快的方法](http://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join)。您可能需要添加索引以加快查詢速度。 –
你可以發佈您的查詢。 –
你可以用'temporary-table'替換'table-variable'嗎?根據您的實例設置,服務器可以選擇使用並行計劃並優化查詢。 「表變量」不能成爲這種計劃的一部分,因爲服務器「認爲」它只有一行。 – gotqn