SQL、While ループ、Recursive Stored proc、または Cursor でどちらが高速ですか? ストアド プロシージャのいくつかの場所でパフォーマンスを最適化したい。私が最適化しているコードは、ファイルへの出力用にいくつかの文字列をフォーマットします。
4 に答える
SQL Server を使用していると仮定します。
まず第一に、ステートメントで誰かが言ったように、再帰的なストアド プロシージャは可能ですが、スタック サイズのために SQL Server ではお勧めできません。したがって、深く再帰的なロジックは壊れます。ただし、せいぜい 2 ~ 3 レベルの入れ子しかない場合は、再帰を使用するか、少し再帰的なCTEを使用してみてください (SQL Server 2005 以降)。CTE に頭を悩ませることができれば、これは非常に便利な手法です。測定はしていませんが、CTE を使用したいくつかの場所でパフォーマンスの問題が発生したことはありません。
一方、カーソルはパフォーマンスを大幅に消費するため、私 (およびインターネットの半分) は、頻繁に呼び出されるコードではカーソルを使用しないことをお勧めします。しかし、カーソルはより古典的なプログラミング構造でありforeach
、C# の に似ているため、複雑な複数内部選択 SQL の怪物よりも、データ操作にカーソルを使用する SQL コードを見て、理解し、維持する方が簡単だと感じる人もいます。時々呼び出されるコードでそれらを使用するのは最悪の考えではありません。
と言えばwhile
、プログラミングの考え方をセットベースからプロシージャベースに移行することもできるため、比較的高速でリソースをあまり消費しませんが、発行するデータ操作ステートメントの数を劇的に増やすことができますデータベース自体。
要約すると、パフォーマンスが最優先される複雑なストアド プロシージャを作成する必要がある場合は、次のようにします。
- セットベースのアプローチ (内部選択、結合、結合など) の使用
- CTE の使用 (経験豊富なユーザーには明確で扱いやすいが、初心者には少し怪しい)
- 制御フロー ステートメントの使用 (if、while...)
- カーソルの使用 (手続き型コード、わかりやすい)
その順序で。
コードの使用頻度がはるかに低い場合は、おそらく 3 と 4 を 1 と 2 の前に移動しますが、これも、多数のテーブルと多数のリレーションを使用する複雑なシナリオの場合のみです。もちろん、YMMV です。実際にパフォーマンスを測定するために、実際のシナリオで作成した手順をテストします。実際の測定値を取得しても、変更によって状況が改善されているのか悪化しているのかを判断する方法はありません。
また、コードはデータと同じ速さしかないことを忘れないでください。優れた索引付けに代わるものはありません。
D) 上記のいずれでもない。
セットベースの方法は、ほとんどの場合、最速の方法です。実際のコード (または近似値) が何であるかを知らなければ、それが可能かどうか、またはどの方法が最も速いかを判断するのは困難です。
最善の策は、考えられるすべての方法をテストして、どれが本当に最速かを確認することです。
パフォーマンスを向上させたい場合は、SET ベースの操作を検討する必要があります。While ループとカーソルは基本的に同じものです。SQL は SET で機能します。手続き型言語ではありません。意図したとおりに使用してください。
ループとカーソルは相互に排他的ではありませんが、再帰ストアド プロシージャが最も遅くなる可能性があります。カーソル操作は非常に高速 (IME) ですが、外部 (非 SQL) コードからしか使用したことがありません。他のポスターは正しいです。セット指向の方法で処理を行うことができれば、最高のパフォーマンスが得られます。