カーソルを使用してあるテーブルから別のテーブルにデータをコピーする

私はBookと呼ばれる本当に大きなテーブル(約1,300万行)を持っています。ブックテーブルの列にプライマリキーを設定したいのですが、非常に大きなテーブルであるため、更新中にサーバーがクラッシュします。メモリが不足しています。だから、私はBookTempテーブルを作成しました。私はこの空のテーブルにすべての主キーを設定し、ブックからBookTempテーブルにデータを挿入したいと思います。しかし、私はすぐにそれをやり直すと再びメモリが使い果たされます。だから私は、毎回10,000行を挿入し、RAMを消去するためにカーソルを使用すると思ったが、私は本当にカーソルに新しいので、その点であなたの助けが欲しいです。

SQL Server 2008 R2を使用しています

0
サーバーがクラッシュしますか?私は本当にそれは想像できません。たぶん反応しなくなるかもしれませんが、確かにクラッシュすることはありません。データを追加する前に、データベース復旧モデルを「シンプル」に切り替えてみてください。プライマリキー(安全のために完全バックアップを行う)。この方法では、操作はログに記録されず、より迅速に実行されます。トリガーを無効にすることも良い考えです。
追加された 著者 Tomalak,

2 答え

テンポラリテーブルを反復するためにwhileループを使うことをお勧めします。例ここをクリックしてください。

または、これを変更するだけでもかまいません:

DECLARE @counter AS INT = 0;
DECLARE @batch_size AS INT = 10000;
WHILE (@counter < (SELECT MAX(id) FROM temp_table))
BEGIN
  INSERT INTO the_table
  SELECT * FROM temp_table
  WHERE id BETWEEN @counter AND (@counter + @batch_size - 1);

  SET @counter = @counter + @batch_size;
END
1
追加された

3つのコマンドを実行すると、SQL Serverのキャッシュをクリーンアップしてメモリを解放します。

DBCC FREESYSTEMCACHE
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE 

しかし、それは進行中の操作で使用することができますので、上記のDBCCコマンドを実行してメモリをクリアするたびに10000を挿入した後、ブロークエリを参照してください。

DECLARE @counter INT = 1
DECLARE cur_Data_Transfer CURSOR FOR  -- Cursor declared
SELECT column1, column2  -- select desired columns
FROM Book 

OPEN cur_Data_Transfer  --Opening Cursor
FETCH NEXT FROM cur_Data_Transfer INTO @column1, @column2  --Put values to variable

WHILE @@FETCH_STATUS = 0  -- Faching is success
BEGIN  
       INSERT INTO BookTemp (column1, column2) -- Inserting to temptable
            VALUES(@column1, @column2)
       IF @counter = 10000
       BEGIN    
        DBCC FREESYSTEMCACHE -- Clear System Cache
        DBCC FREEPROCCACHE   -- Clear Proc Cache
        SET @counter = 0     -- Restarting counter
       END
       FETCH NEXT FROM cur_Data_Transfer INTO @column1, @column2
       SET @counter = @counter + 1
END  
CLOSE cur_Data_Transfer  -- Closing cursor
DEALLOCATE cur_Data_Transfer -- De-allocating 
0
追加された