4

VIEW_MYTABLEたとえば、50 列の SQL ビューがあるとします。

オプション 1 :

with CTE_MYQUERY1 as (
  select [VIEW_MYTABLE].*
  from [VIEW_MYTABLE]
  /*some complex where clause*/
)

オプション 2 :

with CTE_MYQUERY2 as (
  select [COLUMN_1], [COLUMN_2], [COLUMN_3], ...., [COLUMN_10]
  from [VIEW_MYTABLE]
  /*some complex where clause*/
)

select *私の理解によると、列が定義されている選択は常にステートメントよりも高速です。この 2 番目のクエリでは、ビュー内の 50 列のうち 10 列のみを選択していることに注意してください。

私は両方の結果を同じにしていますか?CTEが内部でどのように機能するかを誰かに教えてもらえますか?最初に結果セットを生成してから、それを後続のクエリ(SELECT私の場合はクエリ)に送りますか?

4

3 に答える 3

7

これら 2 つのクエリの実行時間には、識別可能な違いはまったくないと予想されます。

ただし、パフォーマンス上の理由からではなく、依然としてSELECT * に反対することをお勧めします。エンジンがメタデータ内の列名を検索しなければならないため、 SELECT * は効率が悪いという古くからの神話がありますが、実際には、記述した列名を検証するための検索が依然として存在し、名前を取得するための追加コストは、結果セットのサイズに関係なく、人間には気付かれません。

私が SELECT * に反対する理由は次のとおりです。

  • テーブルのすべての列 (またはすべての行ですが、それは別の話です) が必要になる可能性はほとんどありません。必要以上の列をプルバックしている場合は、不必要な I/O を行っており、SQL Server にテーブル/クラスター化インデックス スキャンを強制的に実行させている可能性があります。

  • すべての列が必要な場合でも、SELECT * を使用すると、後でコード内で検出しにくい問題が発生する可能性があります。誰かがテーブルの真ん中に列を挿入したらどうなるでしょうか? 列を削除しますか? 列を追加しますか? 列の名前を変更しますか? これらのいくつかはすぐに検出されますが、これがあらゆる種類のデバッグが困難な問題を引き起こす可能性があるケースを示しました。


CTE が一般的にどのように機能するかについては、ここではかなり幅広い質問です。私はこれらの記事から始めます:

http://www.simple-talk.com/sql/t-sql-programming/sql-server-cte-basics/

https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008/ms190766(v=sql.100)

于 2012-08-24T20:06:06.593 に答える
1

パフォーマンスを低下させる主なSELECT *原因は、クエリが実際に必要とされるよりもはるかに多くのデータを取得するために時間を無駄にすることです。ただし、SELECTどのデータを取得するかを決定するのは、クエリの主要部分の句です。* (非再帰的) 共通テーブル式は、一種の 1 回限りのビューと考えることができます。それを使用するクエリで参照されていない CTE の列は、事実上無視されてしまいます。ビューに対してクエリを実行する場合と同様に、エンジンは必ずしもビュー内のすべての列を取得するとは限らず、要求したすべての列だけを取得します。

私の推測では、例から除外した CTE を使用するクエリはどちらの場合も同じであるため、両方の CTE で同じパフォーマンスが得られます。このため、最初のオプションで参照されている追加の列は、完全なクエリによって取得されるデータに影響を与えることはありません。

*追加: わかりやすくするために、これはSELECTs の場合のみです。WHEREandJOIN句は、列がどこに表示されても読み取る必要がある列に影響を与えます。

于 2012-08-24T20:30:42.227 に答える
0

絶対に必要な数よりも多くの列または行のデータをクライアントに返さないでください。これにより、サーバーのディスク I/O とネットワーク トラフィックが増加するだけであり、どちらもパフォーマンスに悪影響を及ぼします。ステートメントでは、行を返すためにSELECT使用しないSELECT *でください。常にSELECT、この特定のクエリで返される必要がある列を正確にステートメントで指定し、それ以上の列ではありません。ほとんどの場合、WHEREクライアントがすぐにタスクを実行する必要がある行のみに送信される行数または行数を減らす句を含めるようにしてください。

私の意見では、大きな違いはWHERE、主なアクションが行われる場所、関連するインデックスなどと同様に、複雑な句になります。

とはいえ、ほぼすべてのシナリオで 2 番目の方が優れたパフォーマンスを発揮すると思います。

SQL Central に関する Steve Jonesによる詳細な記事を確認してください。

于 2012-08-24T19:58:23.530 に答える