web-dev-qa-db-ja.com

ストアドプロシージャと生のクエリの効率

私はこの議論の両側で多くを読みました:生のクエリに対してストアドプロシージャのみを使用することによって得られる大きなパフォーマンスの向上はありますか? SQL Serverに特に関心がありますが、すべてのデータベースに関心があります。

23
stimms

SQL Server 2008以降ではそれほどではありませんが、まだ存在しています。つまり、実行プランキャッシュとSQL Serverは、送信されたクエリを自動パラメーター化できます。ストアドプロシージャ(内部に動的SQLがない)を使用する場合、クエリは既にパラメーター化されているため、SQL Serverはプランは既にプランキャッシュに格納されているため、実行時にクエリごとにプランを生成する必要があります。

また、ストアドプロシージャを使用するときになくなるセキュリティの問題(動的SQL、最小限の権限など)を忘れないでください。

アプリがベーステーブルに対して動的SQLを使用して、テーブル内のデータを選択、挿入、更新、および削除する場合、アプリケーションはそれらすべてのオブジェクトに対する権限を直接持っている必要があります。したがって、誰かがSQLインジェクションを使用してサーバーにアクセスすると、それらのテーブルのすべてのデータをクエリ、変更、または削除する権限が与えられます。

ストアドプロシージャを使用している場合は、ストアドプロシージャを実行して、ストアドプロシージャが返す情報のみを取得する権限しかありません。簡単な削除ステートメントを発行してすべてを吹き飛ばす代わりに、データを削除するためにどの手順を使用できるかを理解してから、その手順を使用して削除する方法を理解する必要があります。

SQLインジェクションがデータベースに侵入する最も簡単な方法であることを考えると、これは一種の重要なことです。

31
mrdenny

Dennyの回答の補足として、procsでクエリが使用された結果として作成された、単発または低使用のアドホック実行プランで大量のバッファープールメモリが浪費されるシステムを見つけることは珍しくありません。

最近の最悪のケースでは、8GBがインスタンスに割り当てられ、3GBのプランキャッシュ、2.5GBのシングルユースプラン。これらの大半はSQL2005であるため、アドホックワークロードの最適化設定を試すことはできませんでした。

生のクエリに対するプロシージャの正当化にパフォーマンスを含めることは確かに難しくなっています。私にとって今最も強力な議論の1つは、「プロシージャを使用すると、パフォーマンスの問題が発生したときに手助けするのがはるかに簡単になる」です。動的/ linq/ormインターフェースはチューニングを妨げませんが、オプションを厳しく制限する可能性があります。

10

SQL Serverは、ストアドプロシージャとアドホックSQLを同じ方法でキャッシュして最適化します。たとえば、この手順は次のとおりです。

create procedure dbo.TestSB(@id int) as select * from Orders where id = @id

以下と同様に最適化およびキャッシュされます。

select * from Orders where id = @id

ただし、次のアドホックSQLは、ハードコードされた値のため、効果的にキャッシュできません。

select * from Orders where id = 42

パフォーマンスは同じですが、ストアドプロシージャを使用するのには十分な理由があります。ストアドプロシージャは、DBAとアプリケーション開発者を明確に分離します。貴重なデータと絶えず変化するプログラムの間に追加の防御層を設けることは良いことです:)

7
Andomar