web-dev-qa-db-ja.com

SQL Server SELECT INTOと一時テーブルによるブロック

したがって、最近DBAは、次の構文を使用できないことを伝えようとしています。

SELECT X, Y, Z
INTO #MyTable
FROM YourTable

この構文では、ストアドプロシージャの実行中にTempDBがロックされるため、環境で一時テーブルを作成します。今、私は一時テーブルがどのように機能するか、実行の範囲、クリーンアップなどを詳しく説明する多くのものを見つけました。しかし、私の人生では、その使用のためにブロックについては何も見ていません。

すべての一時テーブルに対してCREATE TABLE #MyTable ...を実行する必要はないという証拠を見つけようとしていますが、どちらも証拠を見つけることができません。私は洞察を探していますSO人々が持っています。

追加情報

現在SQL Server 2005を使用しており、間もなくSQL Server 2008(Enterpriseエディション)になる予定です。

26
Mitchel Sellers

そのアドバイスはあちこちに浮かんでいます 長い間

SQL Server 6.5のボトルネック

多くの人は、SELECT ... INTOクエリを使用して、次のような一時テーブルを作成します。

SELECT * INTO #TempTable FROM SourceTable

これは機能しますが、SELECTステートメントの期間中、tempdbデータベースに対してロックを作成します(ソーステーブルの大量のデータをトロールしている場合はしばらく時間がかかりますが、SELECT ... INTOが先頭にある場合はさらに長くなります)実行時間の長い明示的トランザクションの場合)ロックが設定されている間、他のユーザーは一時テーブルを作成できません。ボトルネックの実際の場所は、tempdbシステムテーブルのロックです。 SQL Serverの以降のバージョンでは、ロックモデルが変更され、問題は回避されています。

幸い、SQL 6.5でのみ問題でした。 7.0以降で修正されています。

34
BradC

これはおそらく長い間浮かんで、さまざまな「コンサルタント」のポケットに餌を与えます。すべての神話のように、それは真実のカーネルと多くのBSを持っています。

真実:SQL 2000以前のバージョンには、tempdbでのエクステントの割り当てに関する既知の競合問題がありました。競合は実際にはすべてのデータベースで当てはまりましたが、tempdbの使用量が多いため、tempdbでより見やすくなっています。 KB328551 に記載されています。

Tempdbデータベースが頻繁に使用されている場合、SQL Serverがページを割り当てようとすると競合が発生する可能性があります。

Sysprocessesシステムテーブルの出力から、waitresourceは "2:1:1"(PFSページ)または "2:1:3"(SGAMページ)として表示される場合があります。競合の程度によっては、これにより、SQL Serverが短期間応答しないように見えることもあります。

これらの操作はtempdbを頻繁に使用します。
一時テーブル(ローカルまたはグローバル)の作成と削除を繰り返しました。
tempdbをストレージの目的で使用するテーブル変数。
カーソルに関連付けられた作業テーブル。
ORDER BY句に関連付けられた作業テーブル。
GROUP BY句に関連付けられた作業テーブル。
ハッシュプランに関連する作業ファイル。

これらのアクティビティを大量に使用すると、競合の問題が発生する可能性があります。

トレースフラグ-T1118は、SQLが混合ページ割り当てにラウンドロビンアルゴリズムを使用するように強制するSQL Server 2000 SP3で追加されました。この新しいアルゴリズムは、CPUごとに1つずつある一連の同じサイズのファイルの上にtempdbを展開する慣行と相関関係がある場合、競合を緩和します。トレースフラグはSQL 2005/2008にも存在しますが、必要になる可能性ははるかに低くなります。

この神話の他のすべてはかなりBSです。

  • #tempテーブルを使用するとブロッキングが発生しますか?いいえ。最悪の場合、SQL 2000以前では負荷の下での競合が増加しますが、それは何かをブロックするとはほど遠いです。最初に測定し、これが事実であることを確認する必要があります。その場合は、改善策を展開します(CPUごとに1つのtempdbファイルを割り当て、サイズを同じにして、-T1118をオンにします)。
  • Select ... into #tempは、selectの期間中何かをブロックしますか?あんまり。
  • Select ... into #tempは、selectを含むストアドプロシージャの実行中に何かをブロックしますか?地獄いいえ。その主張を読んだだけで、私は笑い出した。

詳細については、次の記事を参照してください: TF1118に関する誤解

17
Remus Rusanu

次のことをしてみませんか?

SELECT X, Y, Z
INTO #MyTable
FROM YourTable
WHERE 1 = 2

ステートメントは即座に実行されます-一時テーブルを作成し、可能なロックを回避します。次に、通常どおりに挿入できます。

INSERT #MyTable
SELECT X, Y, Z
FROM YourTable
10
Eric Pelot

トランザクション内で#tempテーブルを作成すると、ブロッキングが発生する可能性があります。これは一般的にはお勧めできませんが、多くのことを行ってきました。

ただし、この原因となるブロッキングは、tempdbの一部のシステムテーブルにあり、一時テーブルの作成による他の接続には影響しません(おそらく2000より前のSQLバージョンを除く)。コミットされていない読み取りにトランザクション分離レベルを設定しない限り、tempdbでsp_spacesusedを実行するとブロックされることを意味します。また、SSMSからtempdbのプロパティを表示すると、コミットされた読み取りトランザクション分離レベルを使用しているため、失敗してタイムアウトすることは間違いありません。

1
IainS

SELECT INTO #temp_tableは、実行中の作業の一部がテーブルの作成であるため、ステートメントの期間中、tempdbでShemaロックを保持します。これは、最初にCREATE TABLE #....を使用してテーブルを作成し、次にセットベースのINSERTを実行する場合とは根本的に異なります。 SELECT INTOINSERTよりも優れています。特に、データベースの復旧モデルが単純なログまたは一括ログの場合、操作のログは最小限に抑えられます。

0
Michael Lutz

SELECT INTOはtempdbをブロックしないように修正されていますが、一部のシステムテーブルがブロックされているため、テスト中などのコードを書くときは注意が必要です。

参照: http://www.sqlservercentral.com/Forums/Topic1642797-2799-1.aspx

0
SeeCoolGuy

ロックの証拠がないということは、ロックがないことを意味します。それがあなたの証拠です。一時テーブルを作成するメソッド(CREATEまたはSELECT ... INTO)がTempDBのロックに違いをもたらすのはなぜですか?

0
KM.

まあそれが本当ならmssqlは問題を抱えるでしょう。どんな大きなクエリでもtempdbを利用して行のコピーを保持できるからです。多くの場合、これはクエリプランでテーブルスプールとして表示されるか、バケットのメモリが不足している場合にHASH JOIN演算子で使用できます。

Mssqlがメモリに格納しようとすると、テーブル変数を使用して、変数が大きくなった場合にtempdbに移動することができます。

DECLARE @foo TABLE (x int, y int, z int)
INSERT INTO @foo(x, y, z) SELECT x, y, z FROM YourTable

もちろん、一時テーブルとコピーが最初に必要かどうかを評価する必要があります。クエリが非常に複雑で、一時テーブルを使用する方がはるかに読みやすい場合でも、一時テーブルが価値があるほど複雑になる可能性もあります。

0
Chris Chilvers