0

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

如果 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 检查之后省略了部分。之后,如果 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
4

3 回答 3

0

正如@gotqn 所说,首先使用临时表。填表后在 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

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

于 2016-01-14T08:08:42.473 回答
0

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

(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”所说,索引也将有助于提高性能

于 2016-01-14T07:19:14.127 回答
0

嗯,答案很基本。@Felix 和 @TT 提出了正确的建议。谢谢!

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

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

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

于 2016-02-07T04:18:25.350 回答