web-dev-qa-db-ja.com

SQL-Serverパフォーマンス:ストアドプロシージャとビューのどちらが高速ですか?

SQL Server 2005/2008、ストアドプロシージャ、またはビューで高速なものは何ですか?

編集:あなたの多くが指摘したように、私はあまりにもあいまいです。もう少し具体的にしようと思います。
ビュー内の特定のクエリと、ストアドプロシージャ内のまったく同じクエリのパフォーマンスの違いを知りたいと思いました。 (それらの異なる機能を指摘するすべての回答に感謝します)

38
7wp

この投稿で何度か述べたように、ストアドプロシージャ(SP)とSQLビューは異なる「獣」です。

クエリプランのキャッシュに関連するパフォーマンス上の考慮事項、ストアドプロシージャへのバインドに関連する時間などを除外する場合(フリンジケースを除き、一般的にマイナー)2つのアプローチは全体的に同等のパフォーマンスです-wise。ただし...

ビューは、単一のSELECTステートメントで表現できるものに制限されますが(CTEやその他のいくつかのトリックを使用することもあります)、一般的にはビューはクエリの宣言形式に関連付けられますです。他方のストアドプロシージャでは、さまざまな手続き型構造体(および宣言型のもの)を使用できます。その結果、SPを使用すると、特定の問題を解決する方法を手作業で作成できます)より効率的なクエリ(単一の宣言クエリに基づいて)SQL Serverのクエリオプティマイザーが実行した場合よりもこれらの場合、SPははるかに高速になる可能性があります(ただし、オプティマイザーは非常にスマートであり、SP同等のビューよりもはるかに遅くするのにそれほど時間はかかりません。)

これらのパフォーマンスの考慮事項とは別に、SPはより汎用性が高く、ビューよりも幅広い問い合わせとアクションを可能にします。

69
mjv

残念ながら、彼らは同じタイプの獣ではありません。

ストアドプロシージャはT-SQLステートメントのセットであり、CANはデータを返します。あらゆる種類のロジックを実行でき、必ずしも結果セットでデータを返すとは限りません。

ビューはデータの表現です。主に、基になる結合を持つ1つ以上のテーブルの抽象化として使用されます。常に1行または複数行の結果セットです。

あなたの質問は次のようなものだと思います。

どちらが速いですか:ビューからのSELECTing、またはストアドプロシージャ内の同等のSELECTステートメント、同じwhere句で結合を実行する同じベーステーブルがある場合

12
p.campbell

これは、答えがすべての場合に当てはまるという点で、実際に答えられる質問ではありません。ただし、SQL Server固有の実装の一般的な答えとして...

一般に、ストアドプロシージャは、ストアドプロシージャを初めて保存して実行するときにサーバーがあらゆる種類の最適化を行うため、直接SQLステートメントよりも高速である可能性が高くなります。

ビューは、基本的に保存されたSQLステートメントです。

したがって、一般に、ストアドプロシージャは、それぞれのSQLステートメントが同じ場合、SQLステートメントが最適化の恩恵を受けることができる場合、ビューよりも高速になる可能性が高いと言えます。それ以外の場合、一般に、パフォーマンスは似ています。

私の答えをサポートするこれらのリンクのドキュメントを参照してください。

http://www.sql-server-performance.com/tips/stored_procedures_p1.aspx

http://msdn.Microsoft.com/en-us/library/ms998577.aspx

また、SQL Serverのパフォーマンスを最適化するすべての方法を探している場合は、上記の2番目のリンクから始めるのが適切です。

8
David

優れた安全なモジュラーシステムを構築し、ストアドプロシージャを使用する場合、複数のsqlコマンドを実行でき、フロー制御ステートメントを持ち、パラメーターを受け入れるため、データをより細かく制御できるため、ストアドプロシージャを好みます。ストアドプロシージャでできるビューでできることはすべて。ただし、ストアドプロシージャでは、はるかに柔軟に行うことができます。

5
RRUZ

要するに、いくつかの複雑なクエリでの経験に基づいて、ストアドプロシージャは関数よりも優れたパフォーマンスを提供します。

ただし、選択クエリまたは結合クエリでストアドプロシージャの結果を使用することはできません。

別のクエリで結果セットを使用したくない場合は、SPを使用することをお勧めします。

そして、残りの詳細と相違点は、このフォーラムや他の場所の人々によって言及されています。

4
Tejasvi Hegde

ストアドプロシージャとビューは異なり、目的も異なります。私は、ビューを固定クエリとして見ています。ストアドプロシージャをコードモジュールと見なします。

たとえば、tblEmployeesDateOfBirthという2つの列を持つMaleFemaleというテーブルがあるとします。

男性従業員のみを除外するviewEmployeesMaleというビューは非常に便利です。 viewEmployeesFemaleというビューも非常に便利です。これらのビューはどちらも自己記述的であり、非常に直感的です。

ここで、25〜30歳のすべての男性従業員のリストを作成する必要があるとしましょう。この結果を生成するストアドプロシージャを作成する傾向があります。ビューとして構築することはほぼ確実ですが、私の意見では、ストアドプロシージャの方がこれに対処するのに適しています。特にヌルが要因である場合の日付操作は、非常に注意が必要になります。

別の考え方は、ストアドプロシージャを使用してビューを選択することだと思います。これにより、アーキテクチャが疎結合システムになります。スキーマを将来変更することに決めた場合、フロントエンドが破損することを「それほど」心配する必要はありません。

私が言っているのはsp vs viewsではなく、spとviewだと思います:)

3
JustinT

その他の考慮事項:SPとビューの間のパフォーマンスは本質的に同じですが(まったく同じ選択を実行している場合)、SPは同じクエリの柔軟性が高まります。

  • SPは、結果セットの順序付けをサポートします。つまり、ORDER BYステートメントを含みます。ビューでこれを行うことはできません。
  • SPは完全にコンパイルされ、それを呼び出すにはexecのみが必要です。ビューを呼び出すにはSELECT * FROM viewが必要です。つまり、ビューでコンパイルされたselectを選択します。
0
IronRod

詳細なパフォーマンス分析が見つかりました: https://www.scarydba.com/2016/11/01/stored-procedures-not-faster-views/

コンパイル時間の比較:

ビュー自体とストアドプロシージャのコンパイル時間には違いがあります(ほとんど同じでした)。数千の実行でのパフォーマンスを見てみましょう。

AVGを表示:210.431431431431

Stored Proc w/View AVG:190.641641641642

保存済みProc AVG:200.171171171171

これはマイクロセンドで測定されるため、10mcまたは5%の差はわずかであるため、表示される変動はI/O、CPUなどのわずかな差異になります。

違いがあるので、コンパイル時間を含む実行時間はどうですか:

クエリ期間ビューAVG:10089.3226452906

Stored Proc AVG:9314.38877755511

Stored Proc w/View AVG:9938.05410821643

結論

コンパイル時間の違いを除いて、問題のクエリが同じ場合、ビューは実際にストアドプロシージャとまったく同じように実行されることがわかります。

0
Nabster

私はこれを「議論」に変えるべきではないことを知っていますが、これに非常に興味があり、特定の状況の経験的観察、特に上記のすべてのコメントを参照して共有したいと思いましたストアドプロシージャとビュー内から実行される同等のSELECTステートメントは、ほぼ同じパフォーマンスを備えている必要があります。

別のデータベース(db "B")の5つのテーブルを結合するデータベース "A"にビューがあります。 SSMSのdb "A"に接続し、ビューからSELECT *を実行すると、250000行を返すのに3分以上かかります。ビューのデザインページからselectステートメントを取得し、SSMSで直接実行すると、25秒未満かかります。同じ選択ステートメントをストアドプロシージャに入れると、そのプロシージャを実行したときに同じパフォーマンスが得られます。

絶対的なパフォーマンスを観察することなく(db "B"は、私たちが触れてはならないAXデータベースです!)、この場合SPはビューを使用して同じデータを取得するよりもはるかに高速であり、これはこの特定のケースの他の多くの同様のビューに適用されます。

私はしません思考他のデータベースへの接続を作成することと関係がありますが、ビューを使用して何らかの方法で接続をキャッシュすることはできませんが、選択は2同じSSMSウィンドウで繰り返し、各クエリのパフォーマンスは一貫したままです。また、db "B"に直接接続し、dbname.dbo .... refsなしでselectを実行すると、同じ時間がかかります。

何か考えはありますか?

0
Ade