2017-01-12 7 views
1

このクエリを最適化するのに役立つ人はいますか?私はケースステートメントのうち2つしか書いていませんでしたが、実際には、この例(下の2つ)に示すように、そのようなケースはすべて30個のネストされています。TSQL複数のネストされたケースクエリの最適化

SELECT * 
FROM QS 
INNER JOIN R ON (CASE 
        WHEN R.FieldCode = 'L' 
         THEN --- 
       CASE 
        when (
        (R.Match = 1 AND QS.lineid 
        IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue))) 
        OR (R.Match = 0 AND QS.lineid NOT IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue)))) then 1 
        ELSE 0 
       END 
      ---- 
     WHEN R.FieldCode = 'D' 
      THEN 
       CASE 
        when ((R.Match = 1 AND QS.productid 
        IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue))) 
        OR (R.Match = 0 AND QS.productid NOT IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue)))) then 1 
        ELSE 0 
       END 
END)=1 
+0

最適化が必要なクエリ(パフォーマンスが低下する、または面倒で極端に長い)とは何か「間違っていますか?おそらく、FieldCode、Match、ProductId、FieldValueなどを取るスカラー関数を書くのが最善です。すべてのロジックを論理的に狂ったクエリにまとめることができます(そして再利用することができます) –

+0

これはそのままのスローです – DinaDee

答えて

0

それは二回、テーブル全体を列挙し、それぞれに複数のテストをやってレコードごとに行く必要があるため、データベースエンジンがまったく最適化を行うことができないので、これは、本当に悪いSQLコードです。あなたはまったくCASEせずにこれを行うことができます

SELECT * 
FROM QS 
INNER JOIN R ON ( (R.FieldCode = 'L' 
        AND ( (R.Match = 1 AND QS.lineid IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue))) 
          OR (R.Match = 0 AND QS.lineid NOT IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue))))) 
       OR (R.FieldCode = 'D' 
        AND ( (R.Match = 1 AND QS.productid IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue))) 
          OR (R.Match = 0 AND QS.productid NOT IN (SELECT CONVERT(int,s) FROM SplitFunc(',', R.FieldValue)))))     
       ) 
+0

ORケースステートメントよりも優れていますか?私が見ることができるから、あなたがここで変更したものです。 – DinaDee

+0

エンジンがジョインを処理するために使用するプロセスは異なります。 SSMSのクエリ実行計画を見ると、その違いがわかります。 –

0

これはあなたのためのより良い実行していますか?相対的な行数や基礎となるデータが分からないので、スカラー関数を何度も実行する必要がなく、オプティマイザにとってより親切でなければならないので、これははるかに高速で維持しやすくなると思います。

SELECT * -- Change to only get fields you need from QS.* 
FROM (
    SELECT 
     QS.*, 
     ',' + CONVERT(VARCHAR(10), 
      CASE R.FieldCode 
       WHEN 'L' THEN QA.lineid 
       WHEN 'D' THEN QA.productid 
       -- ... 
       END + ',' AS MatchValue, 
     ',' + R.FieldValue + ',' AS FieldValueCSV 
     R.Match 
    FROM QS 
     CROSS JOIN R 
    ) T 
WHERE (T.Match = 1 AND T.FieldValueCSV LIKE '%' + T.MatchValue + '%') 
    OR (T.Match = 0 AND NOT T.FieldValueCSV LIKE '%' + T.MatchValue + '%') 
関連する問題