1

次のパラメーターを持つストアド プロシージャがあります。

@desk VARCHAR(50)

したい

SELECT *
FROM dbo.Desk
WHERE DeskName = @desk

また、 の値が@desk = 'All'.

これを行う最善の方法は何ですか?

4

4 に答える 4

5

次のように、この条件をWHERE句に含めるだけです。

SELECT  *
FROM    dbo.Desk
WHERE   DeskName = @desk
OR      @desk = 'All'

Martin Smith が以下にコメントしているように、これのパフォーマンスは最適ではありません。テーブルが小さい場合は、T-SQL コードの明快さ/保守性のために、よりパフォーマンスの高いオプションよりもこの簡潔なアプローチを好むかもしれませんが、彼がリンクしている記事も見てください...

于 2012-06-21T10:11:43.453 に答える
2

@MartinSmithが指摘したように、field = @var or @var = 'ALL'答えのタイプには大きなマイナス面があります...

ストアド プロシージャがコンパイルされると、単一の実行プランが生成されます。そして、その実行計画は、パラメーターが投げることができるすべてのシナリオを処理するのに十分である必要があります。

この特定のケースでは、おそらく(MartinSmith は間違いなく言っています)毎回テーブル全体をスキャンします。これは、そのような実行計画が両方の可能な要件を満たすことができるためです。

事実上、単一のleast-worst case実行計画になります。


@desk = 'ALL'ケース (および)ごとに異なる計画を取得するには、 @desk != 'All'2 つのクエリが必要です。これは、残念なことに、より長くシンプルで洗練されていないコードは、コードのパフォーマンスが大幅に向上することを意味します...

IF (@desk = 'ALL')
  SELECT * FROM dbo.Desk
ELSE
  SELECT * FROM dbo.Desk WHERE deskName = @desk


質問へのコメントで@MartinSmithが投稿したリンクは、これについてさらに詳しく説明しています。SQL の経験のレベルにもよりますが、読むことを強くお勧めします。SQL Server の動作について多くのことを説明しています。しかし、それは非常に奥が深いです。

より単純なアプローチは単純です。試してみてください。

適切な制約とインデックスを使用して、目的に合った現実的なデータ セットを含むテーブルを作成します。次に、可能な回答ごとにストアド プロシージャを作成し、それらをテストします。プロファイラーを使用して、CPU 時間、実際の時間、読み取り、書き込みなどを確認するのが理想的です。

違いが非常に小さいため、「最悪」の回答を受け入れることができ、それを短くすることで利益を得ることができます (したがって、それを「最良」にすることができます)。

実際の時間は短くなりますが、CPU 時間は大幅に長くなります。したがって、同時実行性が高い場合は、最も低い CPU 時間を使用することを決定できます。または、同時実行性が低い場合は、CPU 時間は高くても実際の時間は低くする方が望ましい場合があります。


プログラミングは素晴らしく、多くの考慮事項、トレード、バランスがあります。これと同じくらい単純なSQLの断片でも:)

于 2012-06-21T10:37:30.837 に答える
0

最良かつ簡単なアプローチ:

SELECT * FROM dbo.Desk WHERE deskName = CASE WHEN @desk='All' THEN deskName ELSE @desk END
于 2012-06-21T10:58:04.583 に答える
-1
Declare @Desk varchar(50)

if @Desk = 'All' set @Desk = null

select * from dbo.desk where deskname = coalesce(@desk, deskname)
于 2015-10-27T17:13:49.017 に答える