0

これらは、ストアド プロシージャに渡すビット値の一部であり、これらの値に基づいて where 句が生成されます

@booking bit,
@drs bit,
@manifest bit,
@receiving bit,
@status bit

そのような非常に単純な

if (@booking=0)
Select * from Table where ColumnName='Booking'
if (@drs=1)
Select * from Table where ColumnName=DRS'
--so on based on other bit values

クエリは同じままですが、ビット値に基づいて結果セットを取得し、結果セットをマージします。

単純な日では、このクエリは次のようになります

Select * from Table where ColumnName in ('Booking','DRS')

ストアド プロシージャに複数の if ステートメントを入れたくないので、どうしても 1 つのクエリで作成します。

4

2 に答える 2

2

もう 1 つのオプションは、動的 SQL です。スコットの答えに対して私が言及した問題を防ぐことができます:

このパターンでは 1 つのクエリ プランしか取得できず、ColumnName の値の偏りによってはジョブに最適なプランではない可能性があるため、注意してください。たとえば、「DRS」が表に 1 回表示され、「Booking」が表に 600,000 回表示される場合、これらの結果のそれぞれに対して 2 つの非常に異なる計画が最も効果的である可能性があります...しかし、両方に対して得られる計画は最初にたまたま生成されたプランに依存します。

optimize for ad hoc workloads動的 SQL を使用すると、サーバー設定 (SQL Server 2008 以降を想定) を使用してキャッシュの肥大化を防ぐことができ、OPTION (RECOMPILE). 簡単な例を次に示します。

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'SELECT columns -- never use * in production
  FROM dbo.Table -- always use schema prefix
  WHERE ColumnName = @param OPTION (RECOMPILE);';

DECLARE @param VARCHAR(32);

SET @param = CASE WHEN @drs       = 1 THEN 'DRS'
                  WHEN @booking   = 1 THEN 'Booking'
                  WHEN @manifest  = 1 THEN 'Manifest'
                  WHEN @receiving = 1 THEN 'Receiving'
                  WHEN @status    = 1 THEN 'Status' 
END;

EXEC sp_executesql @sql, N'@param VARCHAR(32)', @param;

それはより醜く、維持するのがより困難ですが、ひどい計画に固執する可能性ははるかに低くなります (そして結果としてひどいパフォーマンスの発作が発生します)。

于 2013-10-26T17:13:03.587 に答える