1

where句でisnullを使用しているクエリのレポートがあり、パフォーマンスの問題が発生しています。これは非常に単純化された例です。 http://www.sqlfiddle.com/#!6/79759/11

クエリは複数値のパラメータを使用しており、通常は1つまたは2つの値を返します。(sqlfiddleのテーブル変数を使用してSSRS複数値パラメーターを複製しようとしました)

select 
  isnull(descrL,descr) as division,
  product
from Upper
left join Lower on product = productL
where isnull(DescrL,Descr) in (@params)

すべての製品を持っている上位部門があります。一部の製品は子部門に存在します。それが下位の区分に存在する場合、それが表示されるべき区分です。

会社パラメータは、上位部門、下位部門、またはその両方を受け入れることができます。

パフォーマンスを向上させるためにクエリを変更する方法についてのアイデアはありますか?

4

2 に答える 2

2
select  descrL as division, product
from Lower 
where DescrL like @params + '%'
union
Select descr, product
from Upper
where Descr like @params = '%'

これは非常にパフォーマンスが高いでしょう。一致が上部の選択で見つかった場合、それはすべてのユニオンではなくユニオンであるため、下部の選択では抑制される必要があります。inの代わりにlikeに注意してください。inを実行する場合、結果を見つけるためにDescrLまたはDescrのインデックスを使用する方法はありません。あなたが好きなら、インデックスはうまく使われます。それを機能させるには、アプリケーションロジックを調整する必要があるかもしれません。

それができない場合は、この解決策があります。データベースにfn_splitを追加する必要があります。 http://msdn.microsoft.com/en-us/library/aa496058(v=sql.80).aspx

    select  descrL as division, product
    from Lower l 
    join dbo.fn_Split(@params, ',') p1
        on l.DescrL = p1.value
    union
    Select descr, product
    from Upper u 
    join dbo.fn_Split(@params, ',') p2
        on u.Descr = p2.value

パフォーマンスの最後のビットを本当に引き出したい場合は、テーブル変数を宣言し、fn_splitを1回だけ実行してテーブル変数にデータを入力してから、2つの結合をテーブル変数にすることができます。したがって、ここでは、列のインデックスも利用しています。これは、クエリを高速化するために必要な主なものです。SQL Serverを実行するときは、常に「実際の実行プランを含める」ことを行い、結果を確認して、テーブルスキャンではなくインデックスシークが表示されていることを確認してください。

編集:私はあなたのsqlfiddleリンクに行きました。以前は見ませんでした。これは機能します。申し訳ありませんが、あなたも部門を選択しているので、組合自体は重複を抑制しません。したがって、not inを使用するか、私が好むように、nullの場合は左アウターを使用する必要があります。

select descrL as division, productL as product
    from Lower l 
    join @params p1
        on l.DescrL = p1.division
    union
    Select u.descr, u.product
    from Upper u 
    join @params p2
        on u.Descr = p2.division
    left join (select productL as product
                from Lower l2 
               join @params p3
                 on l2.DescrL = p3.division) sub1
     on u.product = sub1.product
        where sub1.product is null
order by 2
于 2012-10-17T13:35:28.477 に答える
1

よくわかりませんが、あなたの状況でcteは機能しますか?

;with BothDivs as
(
  select 
  isnull(descrL,descr) as division,
  product
  from Upper
  left join Lower on product = productL
)
select division, product
from BothDivs
where division in (@params)
于 2012-10-16T19:08:10.910 に答える