我有一个包含大约 200,000 条带有 EntityID 列的记录的列表,我将其加载到临时表变量中。
如果 dbo 中不存在临时表中的实体 ID,我想插入 Temp 表变量中的任何记录。实体行表。德博。实体行表包含大约 800,000 条记录。
与dbo相比,该过程非常慢。EntityRows 表有大约 500,000 条记录。
我的第一个猜测是因为 NOT EXISTS 子句,Temp 变量中的每一行都必须扫描 dbo 的整个 800k 行。实体行表以确定它是否存在。
问题:是否有其他方法可以在不使用"不存在"的情况下运行此比较检查,这会产生高昂的成本,并且只会随着dbo的恶化而变得更糟。实体行继续增长?
编辑:感谢评论。这是查询(我在"如果不存在"检查后省略了该部分。之后,如果不存在,我插入到 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
我不确定,但有以下方法可以检查
(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所说,首先使用临时表。 填充表后,在实体 ID 上创建索引。 如果在实体行中没有实体 ID 上的索引,请创建一个。
我经常做这样的事情,我通常使用以下模式:
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 表。它再次快速移动。