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 を使用せずに、この比較チェックを実行する別の方法はありますか?

編集:コメントに感謝します。これがクエリです(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

まあ、答えはかなり基本的なものでした。@Felix と @TT には正しい提案がありました。ありがとう!

ydata.dbo.entity の NameID フィールドに非クラスター化インデックスを配置しました。

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

そのため、dbo.entity テーブル全体をスキャンする代わりに、インデックスを使用して NOT EXISTS 部分をすばやく処理できるようになりました。また動きが速いです。

于 2016-02-07T04:18:25.350 に答える
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 に答える