2009-05-13 24 views
26

私は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は非常に非常に頻繁に呼び出されますので、私の質問はこれまで、ここで同時実行の問題が発生する可能性がありますか?

答えて

28

いいえ。テンポラリ・テーブルの独立したインスタンスが各接続ごとに作成されます。

+0

がわかりましたそれは私が考えたものもあり、ここで何か END行うと、一時テーブルを作成し、それを呼び出すことができました - は を始めるとPROCワーカーを作成します私はそれを落とさなかったときに再び。 しかし、あなたの投稿の光の中で私は、新しいクエリを開くしようと、成功せず、そこからそれを呼び出してみましたし、今私は再び落ち着いています:) –

+0

しかし、パフォーマンスは賢明な主要な並行性の問題があります。 – tpower

+1

@tpower:OPの私の理解は主に共有状態とスレッディング問題の変更に関するものでした。パフォーマンスが影響を受けることは明らかです。 –

17

多分。

接頭辞が#(#example)のテンポラリテーブルは、セッションごとに保持されます。したがって、別の呼び出しが実行中(たとえば、バックグラウンドスレッド)にコードがストアドプロシージャを再度呼び出す場合、作成呼び出しは既に存在するため失敗します。あなたが本当にテーブル変数を使用して心配している場合

ではなく

DECLARE @MyTempTable TABLE 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

これは、ストアドプロシージャ呼び出しの「インスタンス」に固有のものになります。

+2

クライアントが何をしようとしても、SQLセッションを再利用することはできません。 – gbn

+0

"(#example)はセッション単位で保持されます" セッションは接続に基づいていますか?しかしそのclearificationのGBN –

+0

オーケー感謝 - それは一定の時間内にセッションを再利用しますので、あなたがドロップを行うことを忘れてしまった場合は、一時テーブルが十分残っ –

7

実際には、私はSQL Serverについて話しています。 tempテーブル(単一の#を持つ)が存在し、作成されたスコープ内に表示されます(スコープバインド)。ストアドプロシージャを呼び出すたびに新しいスコープが作成されるため、そのテンポラリテーブルはそのスコープ内にのみ存在します。私は、テンポラリテーブルも、そのスコープ内で呼び出されるストアドプロシージャとudfsにも見えると考えています。ただし、ダブルポンド(##)を使用すると、セッション内でグローバルになり、したがって、一時テーブルが作成されるセッションの一部として他の実行中のプロセスに表示され、一時テーブルへのアクセスの可能性があるかどうかを考える必要があります同時に望ましいか否かを判断する。

-1

データベースではすべての#tempテーブルで同じロックが使用されるため、たくさん使用するとデッドロックの問題が発生します。並行性のために@テーブル変数を使用する方が良いです。

+1

-1 SQL Server 6.5以降でロックの問題が発生していません –

-1

可能であれば、@ tempテーブルを使用します。つまり、プライマリキーが1つだけ必要で、従​​属のストアドプロシージャからデータにアクセスする必要はありません。

従属ストアド・プロシージャからのデータにアクセスする必要がある場合は#tempテーブルを使用します(ストアド・プロシージャ・コール・チェーンの悪いグローバル変数です)。ストアド・プロシージャ間でデータを渡すための他の方法はありません。 2番目のインデックスが必要な場合にも使用します(ただし、2つ以上のインデックスが必要な場合は#tempテーブルかどうかは自問自答してください)。

常に #tempテーブルを先頭に宣言してください関数のSQLはストアドプロシージャの作成時に#tempテーブル宣言がある場合、ストアドプロシージャの処理を中止して再コンパイルする必要があります。

+1

-1いいえ、一時オブジェクト(テーブルおよび変数)はSQL Server 2005以降で一般的にキャッシュされるため、再コンパイルは行われません。 http://sqlblog.com/blogs/paul_white/archive/2012/08/17/temporary-object-caching-explained.aspxおよびhttp://technet.microsoft.comを参照してください。com/ja-us/library/cc966545.aspxなど –

0

SQL Server 2008 Books ローカルおよびグローバル一時表を作成できます。ローカル一時表は現在のセッションでのみ表示され、グローバル一時表はすべてのセッションで表示されます。

「#table_temporal

」## table_global

ローカルの一時テーブルを複数のユーザーで同時に実行することができ、ストアドプロシージャ、またはアプリケーションで作成されている場合は、データベースエンジンは、できなければなりません異なるユーザーによって作成された表を区別することができます。データベースエンジンは、これを、各ローカルテンポラリテーブル名に数値サフィックスを内部的に付加することによって行います。

次に問題は発生しません。

2

テーブル変数を使用することを推奨するすべての人には、そうすることに慎重にしてください。テーブル変数は索引付けできませんが、一時表は索引付けできません。少量のデータを処理する場合はテーブル変数が最適ですが、大きなデータセット(50kレコードなど)を処理する場合、一時テーブルはテーブル変数よりもはるかに高速です。

また、try/catchを使用してストアドプロシージャ内で強制的にクリーンアップを行うことはできません。ワーカーストアドプロシージャのtry/catchを実行できるラッパーストアドプロシージャを作成する必要がある場合は、try/catch内で特定のタイプのエラーを検出することはできません(名前解決の遅延によるコンパイルエラーなど)。そこの清掃をしてください。

私は、クエリアナライザを使用していたので、緊張しました。..

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 
関連する問題