私はspの一時テーブルと、それが並行性にどのように影響するかについて疑問に思っていました。 SP MSSQL 08サーバーで作成。
SPがある場合、一時テーブルを作成し、次のように再度ドロップします。
BEGIN
CREATE TABLE #MyTempTable
(
someField int,
someFieldMore nvarchar(50)
)
... Use of temp table here
... And then..
DROP TABLE #MyTempTable
END
このSPは非常に頻繁に呼び出されるため、ここで同時実行の問題が発生する可能性はありますか?
いや。接続ごとに一時テーブルの独立したインスタンスが作成されます。
多分。
1つの#(#example)が前に付いた一時テーブルは、セッションごとに保持されます。そのため、別の呼び出し(バックグラウンドスレッドなど)の実行中にコードでストアドプロシージャを再度呼び出すと、作成呼び出しは既に存在するため失敗します。
本当に心配な場合は、代わりにテーブル変数を使用してください
DECLARE @MyTempTable TABLE
(
someField int,
someFieldMore nvarchar(50)
)
これは、そのストアドプロシージャコールの「インスタンス」に固有です。
そうでもないので、私はSQL Serverについて話しています。一時テーブル(#が1つ)が存在し、作成されたスコープ内で表示されます(スコープにバインド)。ストアドプロシージャを呼び出すたびに新しいスコープが作成されるため、その一時テーブルはそのスコープにのみ存在します。一時テーブルは、そのスコープ内で呼び出されるストアドプロシージャとudfsからも見えると信じています。ただし、ダブルポンド(##)を使用する場合、セッション内でグローバルになり、一時テーブルが作成されるセッションの一部として他の実行プロセスに表示され、一時テーブルにアクセスする可能性があるかどうかを考える必要があります同時に望ましいかどうか。
テーブル変数の使用を推奨しているすべての人は、注意してください。一時テーブルにはインデックスを付けることができますが、テーブル変数にはインデックスを付けることができません。テーブル変数は、少量のデータを扱う場合に最適ですが、より大きなデータセット(5万件のレコードなど)を扱う場合、一時テーブルはテーブル変数よりもはるかに高速です。
また、try/catchに依存して、ストアドプロシージャ内のクリーンアップを強制できないことにも注意してください。特定のタイプの失敗は、try/catch内でキャッチできません(名前解決の遅延によるコンパイルの失敗など)、ワーカーストアドプロシージャのtry/catchを実行できるラッパーストアドプロシージャを作成する必要がある場合は、そしてそこでクリーンアップを行います。
例えばproc worker AS BEGINを作成します-ここで何かをしますEND
create proc wrapper AS
BEGIN
Create table #...
BEGIN TRY
exec worker
exec worker2 -- using same temp table
-- etc
END TRY
END CATCH
-- handle transaction cleanup here
drop table #...
END CATCH
END
SQL Server 2008 Booksによると、ローカルおよびグローバルの一時テーブルを作成できます。ローカル一時テーブルは現在のセッションでのみ表示され、グローバル一時テーブルはすべてのセッションで表示されます。
'#table_temporal
'## table_global
複数のユーザーが同時に実行できるストアドプロシージャまたはアプリケーションでローカル一時テーブルが作成される場合、データベースエンジンは、異なるユーザーが作成したテーブルを区別できる必要があります。データベースエンジンは、各ローカル一時テーブル名に数値の接尾辞を内部的に追加することによりこれを行います。
その後、問題は発生しません。