1

同じ列を使用するストアド プロシージャがありますが、WHERE句が異なります。

このようなもの。

SELECT
     alarms.startt, alarms.endt, clients.code, clients.Plant,
     alarms.controller, alarmtype.atype, alarmstatus.[text]
FROM alarms
INNER JOIN clients ON alarms.clientid = clients.C_id 
INNER JOIN alarmstatus ON alarms.statusid = alarmstatus.AS_id
INNER JOIN alarmtype ON alarms.typeid = alarmtype.AT_id

そして、同じクエリを 3 つの if (条件) に入れました。このWHERE場合、変数に渡されたパラメーターに従って句が変更されます。

すべての if の条件ごとに文字列全体を何度も書く必要がありますか?

または、一度に最適化して、変更されるのは WHERE 句だけですか?

4

6 に答える 6

2

次のようなことを行うと、コードの繰り返しを避けることができます。

WHERE (col1 = @var1 AND @var1 IS NOT NULL)
OR ...
OPTION RECOMPILE;

データベースのパラメーター化設定(単純対強制)を使用して、この動作に何らかの影響を与えることもできます。

コードの繰り返しを回避し、パラメータースニッフィングによる次善の計画を回避する方法は、動的SQLを使用することです。

DECLARE @sql NVARCHAR(MAX) = N'SELECT ...';
IF @var1 IS NOT NULL
  SET @sql = @sql + ' WHERE ...';

これは、サーバー設定「アドホッククエリ用に最適化」を有効にしている場合にうまく機能する可能性があります。

于 2012-06-20T17:18:55.663 に答える
2

する必要はありません。次のようなことで回避できます。

SELECT  *
FROM    [Query]
WHERE   (@Parameter = 1 AND Column1 = 8)
OR      (@Parameter = 2 AND Column2 = 8)
OR      (@Parameter = 3 AND Column3 = 8)

しかし、できるからといって、やるべきだとは限りません。SQL の詳細度が低いからといって、パフォーマンスが向上するわけではないため、次のようなものを使用します。

IF @Parameter = 1
    BEGIN
        SELECT  *
        FROM    [Query]
        WHERE   Column1 = 8
    END
ELSE IF @Parameter = 2
    BEGIN
        SELECT  *
        FROM    [Query]
        WHERE   Column2 = 8
    END
ELSE IF @Parameter = 3
    BEGIN
        SELECT  *
        FROM    [Query]
        WHERE   Column3 = 8
    END

一方、最初のクエリに相当するものは、最適化が向上するため、パフォーマンスが向上するはずです。

于 2012-06-20T16:57:00.400 に答える
1

誰もこれを提案していないので。元のクエリをビューに配置してから、さまざまなWHERE句を使用してビューにアクセスできます。

パフォーマンスを向上させるために、WHERE句で一般的に使用される列がわかっている場合は、ビューにインデックスを追加することもできます(http://msdn.microsoft.com/en-us/library/dd171921(v=sqlを確認してください)。 100).aspx)。

于 2012-06-20T18:05:58.537 に答える
1

私はおそらくSQLステートメント全体を繰り返すことに固執するでしょうが、過去にこれに頼ったことがあります...

WHERE (@whichwhere=1 AND mytable.field1=@id)
  OR (@whichwhere=2 AND mytable.field2=@id)
  OR (@whichwhere=3 AND mytable.field3=@id)

特に読みにくく、遅い場合は実行計画を確認する必要がありますが、コードを繰り返すことはできません。

于 2012-06-20T16:57:14.233 に答える
0

SQLのほとんどのものと同じように、それは状況によって異なります。ここでいくつかの考慮事項があります。

  • WHEREが異なると、実行のクエリプランが大幅に異なります。たとえば、インデックスが付けられた列の1つは、他の2つはインデックス付けされていません。
  • クエリは時間の経過とともに変化する可能性がありますか?つまり、他の列を必要とする顧客の要件
  • WHEREは4、8、16などのオプションになる可能性がありますか。

1つのアプローチは、さまざまなprocを一時テーブルに実行することです。各プロシージャには、独自のクエリプランがあります。

もう1つのアプローチは、動的SQLを使用することです。ここでも、各「クエリ」に独自のプランが割り当てられます。

3番目のアプローチは、オプションごとにSQLを生成するアプリを作成することです。これは、ストアドプロシージャまたはSQL文字列のいずれかです。

次に、データセットを用意し、それに対してテスト駆動開発を行います(これは各アプローチに当てはまります)。

結局のところ、最良の学習ソリューションはおそらくa)SQLについて読むことです。KalenDelaneyInsideSQLは認められた専門家です。b)独自のデータに対して独自のソリューションをテストする

于 2012-06-20T17:17:25.693 に答える