SQL 服务器 - 使用 NOT EXISTS 的替代方法

SQL Server - alternative to using NOT EXISTS

我有一个包含大约 200,000 条记录的列表,其中包含我加载到临时 table 变量中的 EntityID 列。

如果 dbo.EntityRows table 中不存在来自 Temp table 的 EntityID,我想插入来自 Temp table 变量的任何记录。 dbo.EntityRows table 包含大约 800,000 条记录。

与 dbo.EntityRows table 有大约 500,000 条记录时相比,该过程非常缓慢。

我的第一个猜测是因为 NOT EXISTS 子句,Temp 变量中的每一行都必须扫描 dbo.EntityRows table 的整个 800k 行以确定它是否存在。

问题:是否有替代方法 运行 这种不使用 NOT EXISTS 的比较检查,这会产生高昂的成本并且随着 dbo.EntityRows 的继续增长只会变得更糟?

编辑:感谢评论。这是查询(我在 IF NOT EXISTS 检查后省略了部分。之后,如果 NOT EXISTS,我插入 4 tables)。

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

我不确定,但我们可以通过以下方式检查

(SELECT COUNT(er.EntityID) FROM dbo.EntityRows er WHERE er.EntityID = EntityID) <> 0

(SELECT er.EntityID FROM dbo.EntityRows er WHERE er.EntityID = EntityID) IS NOT NULL

EntityID NOT EXISTS  (SELECT er.EntityID FROM dbo.EntityRows er)

EntityID NOT IN (SELECT er.EntityID FROM dbo.EntityRows er)

但根据我的信念,计数会带来良好的性能。 正如'Felix Pamittan'所说

,索引也将有助于提高性能

正如@gotqn 所说,从使用临时 table 开始。在 table 填充后,在 EntityID 上创建索引。如果您在 EntityRows 中的 EntityID 上没有索引,请创建一个。

我经常做这样的事情,我通常使用以下模式:

INSERT INTO EntityRows (
    EntityId, ...
)

SELECT T.EntityId, ...
FROM #tempTable T
LEFT JOIN EntityRows E
ON T.EntityID = E.EntityID
WHERE E.EntityID IS NULL

如果您想了解更多信息,请发表评论。

好吧,答案很简单。 @Felix 和@TT 的建议是正确的。谢谢!

我在 ydata.dbo.entity 的 NameID 字段上放置了一个非聚集索引。

if not exists (select 1 from ydata.dbo.entity
                    where NameID = @CurrentName)

因此它现在可以使用索引快速处理 NOT EXISTS 部分,而不是扫描整个 dbo.entity table。它再次快速移动。