28

そのため、最近DBAは、次の構文を使用できないことを通知しようとしています。

SELECT X, Y, Z
INTO #MyTable
FROM YourTable

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

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

追加情報

現在SQLServer2005を使用しており、まもなくSQL Server 2008(Enterpriseエディション)になります

4

8 に答える 8

35

そのアドバイスは長い間出回っています:

SQL Server 6.5 のボトルネック

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

SELECT * INTO #TempTable FROM ソーステーブル

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

幸いなことに、これは SQL 6.5 のみの問題でした。7.0以降で修正されました。

于 2009-08-19T21:43:02.373 に答える
17

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

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

tempdbデータベースが頻繁に使用されると、SQLServerがページを割り当てようとしたときに競合が発生する可能性があります。

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

これらの操作はtempdbを多用します。
一時テーブル(ローカルまたはグローバル)の作成と削除を繰り返します。
ストレージの目的でtempdbを使用するテーブル変数。
CURSORSに関連付けられた作業テーブル。
ORDERBY句に関連付けられた作業テーブル。
GROUPBY句に関連付けられた作業テーブル。
HASHPLANSに関連付けられた作業ファイル。

これらのアクティビティを頻繁かつ重要に使用すると、競合の問題が発生する可能性があります。

トレースフラグ-T1118がSQLServer2000 SP3に追加され、SQLが混合ページの割り当てにラウンドロビンアルゴリズムを使用するように強制されていました。この新しいアルゴリズムは、CPUごとに1つずつ、同じサイズのファイルのセットの上にtempdbをデプロイする方法と関連付けると、競合を軽減します。トレースフラグはSQL2005/2008に引き続き存在しますが、必要になる可能性ははるかに低くなります。

この神話に関する他のすべては、ほとんどBSです。

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

詳細については、この記事があります:TF1118に関する誤解。

于 2009-08-20T00:30:18.980 に答える
10

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

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

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

INSERT #MyTable
SELECT X, Y, Z
FROM YourTable
于 2010-06-15T21:52:21.407 に答える
1

トランザクション内で #temp テーブルを作成すると、ブロックされる可能性があります。これは一般的には推奨されませんが、私はこれが多く行われているのを見てきました.

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

于 2010-11-02T00:03:37.353 に答える
0

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

于 2009-08-19T21:24:53.360 に答える
0

それが本当なら、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

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

于 2009-08-19T21:42:22.903 に答える
0

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

于 2010-01-22T20:16:43.703 に答える