2017-08-29 9 views
-1

私は、テーブルtblLoginsに200kユーザーのデータが保存されています。SQL Serverのカーソルのパフォーマンスを向上させる方法

別のtableに各ユーザーの30レコードを挿入する必要があります。私はこの作業にカーソルを使用しました。しかし、私が書いたスクリプトには多くの時間がかかります。

2時間で6万人のユーザーのみがデータを挿入しています。

私は解決策についてgoogleを見てきましたが、パフォーマンスを向上させるために関連するものは見つかりませんでした。

以下は私が書いたスクリプトです。

DECLARE @LoginID int 
DECLARE @DomainID int 

DECLARE curDomain CURSOR FAST_FORWARD 
FOR SELECT tbldomains_id FROM tblDomains 

OPEN curDomain 

FETCH NEXT FROM curDomain INTO @DomainID 

WHILE @@FETCH_STATUS = 0 

BEGIN 
--cur2 starts 

DECLARE curLogin CURSOR FAST_FORWARD 
FOR SELECT tbllogins_id FROM tbllogins where tbldomains_id = @DomainID 

OPEN curLogin 

FETCH NEXT FROM curLogin INTO @LoginID 

WHILE @@FETCH_STATUS = 0 

BEGIN 

--code starts 

if not exists(select 1 from tblWidgetProperties where tblLogin_id = @LoginID) 
begin 
Insert tblWidgetProperties values(1,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(2,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(3,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(4,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(5,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(6,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(7,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(8,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(9,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(10,@LoginID,'isEnabled','True') 
Insert tblWidgetProperties values(11,@LoginID,'isEnabled','True') 
end 

if not exists(select 1 from tblWidgetPosition where tblLogins_id = @LoginID) 
begin 
Insert tblWidgetPosition values(3,1.0,@LoginID) 
Insert tblWidgetPosition values(4,1.01,@LoginID) 
Insert tblWidgetPosition values(5,1.02,@LoginID) 
Insert tblWidgetPosition values(11,1.03,@LoginID) 
Insert tblWidgetPosition values(1,2.00,@LoginID) 
Insert tblWidgetPosition values(7,2.01,@LoginID) 
Insert tblWidgetPosition values(9,2.02,@LoginID) 
Insert tblWidgetPosition values(8,2.03,@LoginID) 
Insert tblWidgetPosition values(6,3.0,@LoginID) 
Insert tblWidgetPosition values(2,3.01,@LoginID) 
Insert tblWidgetPosition values(10,3.02,@LoginID) 
end 

--code ends 

FETCH NEXT FROM curLogin INTO @LoginID 

END 

CLOSE curLogin 

DEALLOCATE curLogin 

--cur2 ends 

FETCH NEXT FROM curDomain INTO @DomainID 

END 
+0

はファイルからオプションを読み取っていますか?一括挿入を使用してください。 –

+0

@RadimBačaデータ用のファイルがありません。 –

+0

データをサーバー上のファイルにシリアル化することはできませんか? –

答えて

4

あなたはこれらのようなちょうど2つのインサートを書くことができるはず、のようなすべての

何かで何のカーソル:

;WITH NewData AS (
    SELECT 1 as n UNION ALL 
    SELECT 2 as n UNION ALL 
    SELECT 3 as n UNION ALL 
    SELECT 4 as n UNION ALL 
    SELECT 5 as n UNION ALL 
    SELECT 6 as n UNION ALL 
    SELECT 7 as n UNION ALL 
    SELECT 8 as n UNION ALL 
    SELECT 9 as n UNION ALL 
    SELECT 10 as n UNION ALL 
    SELECT 12 as n 
) 
INSERT INTO tblWidgetProperties (/* Some column list, currently unknown */) 
SELECT nd.n,tl.tbllogins_id,'isEnabled','true' 
FROM 
    NewData nd 
     cross join 
    tblLogins tl 
WHERE 
    tl.tbldomains_id in (select tbldomains_id from tblDomains) and 
    tl.tbllogins_id not in (select tblLogin_id from tblWidgetProperties) 

は、運動は、本質的に同じことを実行するために、読者のために残されていません他のターゲット表の変換。データが行ごとに異なる場合は、NewData CTEに列を追加します。データがすべての行に対して固定されている場合は、上記のように選択範囲内の値をインラインに保ちます。

+0

ありがとうございます。それは素晴らしい作品です。ちょうど2分で約37のlacsレコードが挿入されました。 –

+0

@CodeRiderここではインドの単語を使用しないでください。他の場所の人はそれらを理解できません。 –

+0

@JamesZ - 私は使用法を修正するために使用しました。しかし、私は回り始めます。私は頻繁に使用されるlacsかlakhsが私が意味するものを知っているのを見た。私はなぜインドで名義の単位になるのに十分な重要性を感じているのか分かりませんが、すぐに英語に入っても驚かないでしょう。 –

0

行単位で挿入することは非常に遅くなる可能性があります。データをCSVファイルに準備し、BULK INSERTを使用してジョブを実行します。挿入物を損なうおそれのあるデータの特殊文字に注意してください。

BULK INSERT tblWidgetProperties 
FROM 'c:\temp\WidgetProperties.tbl' 
WITH 
    ( 
    FIELDTERMINATOR =',', 
    ROWTERMINATOR = '\n' 
    ); 

BULK INSERTがオプションでない場合、インサートの速度を監視する必要があります。挿入する表のDisabling triggersが役立ちます。

+0

このCSVファイルは手動で作成する必要がありますか? –

+0

C#とC++でプログラムを作成しますので、CSVファイルを準備してください。どのようにデータを取得するのか分かりません。手動で行うのが適切な場合は、それを実行します。 –

0

あなたはひどい挿入物をしています。 挿入量を減らすには、2つの一時テーブルを作成してみてください。インサートの各セットに対して1つ。その後、あなたは何かのようにすることができます。

if not exists(select 1 from tblWidgetProperties where tblLogin_id = @LoginID) 
begin 
    insert into tblWidgetProperties 
    Select [1],@LoginID,[2],[3]) from #tmpWidgetProperties 
end 

if not exists(select 1 from tblWidgetPosition where tblLogins_id = @LoginID) 
begin 
    Insert tblWidgetPosition 
    select [1], [2], @LoginID from #tmpWidgetPositions 
end 

これを行う前に、CTEとMERGEを見ていきます。

乾杯マーティン

関連する問題