157

どちらがよりパフォーマンスが高いですか、CTEまたはTemporary Tables

4

12 に答える 12

69

それらは異なる概念だと思いますが、「チョークとチーズ」と言うにはそれほど違いはありません.

  • 一時テーブルは、再利用したり、一連のデータに対して複数の処理パスを実行したりするのに適しています。

  • CTE は、再帰するため、または単純に読みやすさを向上させるために使用できます。
    また、ビューやインライン テーブル値関数と同様に、メイン クエリで展開されるマクロのように扱うこともできます。

  • 一時テーブルは、スコープに関するいくつかのルールを持つ別のテーブルです

両方(およびテーブル変数も)を使用するprocを保存しました

于 2009-03-30T19:10:54.997 に答える
56

CTE には用途があります。CTE 内のデータが小さく、再帰テーブルの場合のように読みやすさが大幅に向上する場合です。ただし、そのパフォーマンスは確かにテーブル変数より優れているわけではなく、非常に大きなテーブルを扱う場合、一時テーブルは CTE を大幅に上回ります。これは、CTE でインデックスを定義できず、別のテーブルとの結合が必要な大量のデータがある場合に発生します (CTE は単なるマクロのようなものです)。それぞれに数百万行のレコードがある複数のテーブルを結合している場合、CTE は一時テーブルよりも大幅にパフォーマンスが低下します。

于 2010-04-30T01:28:30.520 に答える
37

一時テーブルは常にディスク上にあるため、CTE をメモリに保持できる限り、(テーブル変数のように) 高速になる可能性が高くなります。

ただし、CTE (または一時テーブル変数) のデータ負荷が大きくなりすぎると、ディスクにも保存されるため、大きなメリットはありません。

一般的に、一時テーブルよりも CTE の方が好きです。CTE は使用後になくなってしまうからです。明示的にドロップすることなどを考える必要はありません。

したがって、最終的に明確な答えはありませんが、個人的には、一時テーブルよりも CTE を好みます。

于 2009-03-27T17:22:11.710 に答える
8

そのため、最適化を担当したクエリは、SQL サーバーで 2 つの CTE を使用して作成されました。28秒かかりました。

それらを一時テーブルに変換するのに2分かかり、クエリには3秒かかりました

結合されていたフィールドの一時テーブルにインデックスを追加し、2秒に短縮しました

3 分間の作業で、CTE をすべて削除することで、12 倍高速に実行できるようになりました。個人的には、CTE はデバッグが難しいため、使用しません。

クレイジーなことに、CTE は両方とも 1 回しか使用されていませんでしたが、それでもインデックスを配置すると 50% 高速であることが証明されました。

于 2016-09-14T18:59:58.910 に答える
4

CTE の優れたパフォーマンスが賢明であると感じた用途の 1 つは、比較的複雑なクエリを、それぞれ数百万行のいくつかのテーブルに結合する必要がある場合でした。

CTE を使用して、最初にインデックス付きの列に基づいてサブセットを選択し、まずこれらのテーブルをそれぞれ数千の関連する行に切り詰めてから、CTE をメイン クエリに結合しました。これにより、クエリの実行時間が指数関数的に短縮されました。

CTE の結果はキャッシュされず、テーブル変数の方が適切な選択だったかもしれませんが、実際にそれらを試してみて、上記のシナリオに適合することがわかりました。

于 2012-09-06T00:32:59.173 に答える
4

パーティーに遅れましたが...

私が働いている環境は非常に制約されており、一部のベンダー製品をサポートし、レポートなどの「付加価値」サービスを提供しています。ポリシーと契約の制限により、通常、テーブル/データ スペースを分離したり、永続的なコードを作成したりするという贅沢は許されません [アプリケーションによっては、多少改善されます]。

IOW、通常、ストアド プロシージャ、UDF、または一時テーブルなどを開発することはできません。MYアプリケーション インターフェイス (Crystal Reports - テーブルの追加/リンク、CR を使用した where 句の設定など) を介してほとんどすべてを行う必要があります。 )。ちょっとした節約の恩恵の 1 つは、Crystal では COMMANDS (および SQL 式) を使用できることです。通常のテーブルの追加/リンク機能では効率的でないいくつかのことは、SQL コマンドを定義することで実行できます。私はそれを通してCTEを使用し、「リモートで」非常に良い結果を得ました。CTE はレポートのメンテナンスにも役立ちます。コードを開発し、DBA に渡してコンパイル、暗号化、転送、インストールし、複数レベルのテストを行う必要はありません。ローカル インターフェイスを介して CTE を実行できます。

CR 付きの CTE を使用することの欠点は、各レポートが個別であることです。レポートごとに各 CTE を維持する必要があります。SP と UDF を実行できる場合は、通常のテーブルで作業しているかのように、SP にリンクしてパラメーターを渡すだけで、複数のレポートで使用できるものを開発できます。CR はパラメーターを SQL コマンドに処理するのが得意ではないため、CR/CTE の側面が欠けている可能性があります。そのような場合、私は通常、CTE を定義して十分なデータ (ただし、すべてのデータではない) を返し、CR のレコード選択機能を使用してそれを細分化します。

だから...私の投票はCTEです(データスペースを取得するまで)。

于 2011-05-18T15:26:33.593 に答える
3

私はこれをテストしました.CTEと非CTE(すべてのユニオンインスタンスに対してクエリが入力された場所)の両方で、約31秒かかりました. CTE により、コードがはるかに読みやすくなりましたが、241 行から 130 行に削減されました。これは非常に優れています。一方、一時テーブルは 132 行に削減され、実行に 5 秒かかりました。冗談抜き。このテストはすべてキャッシュされました。クエリはすべて、以前に複数回実行されました。

于 2014-06-09T21:39:34.903 に答える
2

これは本当に自由形式の質問であり、それはすべて、その使用方法と一時テーブルのタイプ(テーブル変数または従来のテーブル)によって異なります。

従来の一時テーブルはデータを一時DBに格納しますが、これにより一時テーブルの速度が低下します。ただし、テーブル変数はそうではありません。

于 2009-03-27T16:32:09.193 に答える
2

SQL Server での経験から、CTE が一時テーブルより優れているシナリオの 1 つを見つけました。

ストアド プロシージャで一度だけ複雑なクエリから DataSet(~100000) を使用する必要がありました。

  • 一時テーブルは、プロシージャの実行速度が遅い SQL でオーバーヘッドを引き起こしていました (一時テーブルは tempdb に存在する実際の実体化されたテーブルであり、現在のプロシージャの存続期間中持続するため)

  • 一方、CTE では、CTE は次のクエリが実行されるまでしか持続しません。したがって、CTE はスコープが制限された便利なメモリ内構造です。デフォルトでは、CTE は tempdb を使用しません。

これは、CTE がコードを簡素化し、一時テーブルより優れたパフォーマンスを発揮するのに役立つ 1 つのシナリオです。私は2つのCTEを使用しました。

WITH CTE1(ID, Name, Display) 
AS (SELECT ID,Name,Display from Table1 where <Some Condition>),
CTE2(ID,Name,<col3>) AS (SELECT ID, Name,<> FROM CTE1 INNER JOIN Table2 <Some Condition>)
SELECT CTE2.ID,CTE2.<col3>
FROM CTE2
GO
于 2015-09-07T10:08:41.217 に答える