2011-01-25 31 views
2

正直なところ、私の知識のために少し複雑すぎるMSSQLビューを最適化するための助けが必要です。SQL Serverビューの最適化ヘルプ(繰り返しサブクエリ、ケースなど...)

ビューはうまくいきましたが、単純化してより少ないサーバーリソースを使用するために、より少ないサブクエリまたはより良い構造を使用して再作成したいと思います。

主な問題は、同じサブクエリを4回繰り返したケースです...変数に入れて、毎回クエリを繰り返す代わりにCASEで使用できるかどうかを理解しようとしましたが、そうではないようです私には可能...

ここでは、任意の提案が本当に高く評価されますが、DBに関するより多くの情報が必要ならば、私はそれを提供しようとするクエリ

SELECT  dbo.MACCHINE.id_macchina, [...] dbo.VIEW_CANTIERI.indirizzo, 

(SELECT  TOP (1) data_fine 
FROM   dbo.MANUTENZIONI 
WHERE  (id_macchina = dbo.MACCHINE.id_macchina) 
ORDER BY data_fine DESC) 
AS ultima_manutenzione, 

DATEDIFF(day, 
    (SELECT  TOP (1) data_fine 
    FROM   dbo.MANUTENZIONI AS MANUTENZIONI_1 
    WHERE  (id_macchina = dbo.MACCHINE.id_macchina) 
    ORDER BY data_fine DESC), GETDATE()) 
AS data_diff, 

(CASE WHEN 
    stato = 0 
    THEN 'GREY' 
WHEN stato = 2 
    THEN 'BLACK' 
WHEN stato = 1 
    THEN 
     (CASE WHEN 
      DATEDIFF(day, 
      (SELECT  TOP (1) data_fine 
      FROM   dbo.MANUTENZIONI AS MANUTENZIONI_1 
      WHERE  (id_macchina = dbo.MACCHINE.id_macchina) 
      ORDER BY data_fine DESC), GETDATE()) >= 90 
     THEN 'RED' 

     WHEN 
      DATEDIFF(day, 
      (SELECT  TOP (1) data_fine 
      FROM   dbo.MANUTENZIONI AS MANUTENZIONI_1 
      WHERE  (id_macchina = dbo.MACCHINE.id_macchina) 
      ORDER BY data_fine DESC), GETDATE()) >= 80 
     THEN 'ORANGE' 

     WHEN 
      DATEDIFF(day, 
      (SELECT  TOP (1) data_fine 
      FROM   dbo.MANUTENZIONI AS MANUTENZIONI_1 
      WHERE  (id_macchina = dbo.MACCHINE.id_macchina) 
      ORDER BY data_fine DESC), GETDATE()) >= 60 
     THEN 'YELLOW' 

     WHEN 
      (SELECT  TOP (1) data_fine 
      FROM   dbo.MANUTENZIONI AS MANUTENZIONI_1 
      WHERE  (id_macchina = dbo.MACCHINE.id_macchina) 
      ORDER BY data_fine DESC) IS NULL 
     THEN 'RED' ELSE 'GREEN' 

     END) 

END) 
AS colore FROM   dbo.MACCHINE INNER JOIN 
        dbo.MACCHINE_MODELLI ON dbo.MACCHINE.id_modello = dbo.MACCHINE_MODELLI.id_modello INNER JOIN 
        dbo.MACCHINE_TIPOLOGIE ON dbo.MACCHINE_MODELLI.id_tipologia = dbo.MACCHINE_TIPOLOGIE.id_tipologia INNER JOIN 
        dbo.VIEW_CANTIERI ON dbo.MACCHINE.id_cantiere = dbo.VIEW_CANTIERI.id_cantiere INNER JOIN 
        dbo.MACCHINE_PRODUTTORI ON dbo.MACCHINE_MODELLI.id_produttore = dbo.MACCHINE_PRODUTTORI.id_produttore INNER JOIN 
        dbo.CLIENTI ON dbo.VIEW_CANTIERI.id_cliente = dbo.CLIENTI.id_cliente WHERE  (dbo.MACCHINE._del = 'N') 

だ...

答えて

2

私はあなたに気づきますTOP(1)を使用しているので、2005以上でなければなりません。 dateiffの結果をOUTER APPLYサブクエリに保持して、一度しか評価されないようにすることができます。

SELECT 
    M.id_macchina, 
    [...], 
    V.indirizzo, 
    MA.data_fine AS ultima_manutenzione, 
    MA.data_diff, 
    CASE 
    WHEN stato = 0 THEN 'GREY' 
    WHEN stato = 2 THEN 'BLACK' 
    WHEN stato = 1 THEN 
     CASE 
     WHEN MA.data_diff >= 90 THEN 'RED' 
     WHEN MA.data_diff >= 80 THEN 'ORANGE' 
     WHEN MA.data_diff >= 60 THEN 'YELLOW' 
     WHEN MA.data_fine IS NULL THEN 'RED' 
     ELSE 'GREEN' 
     END 
    END AS colore 
FROM dbo.MACCHINE M 
INNER JOIN dbo.MACCHINE_MODELLI I ON M.id_modello = I.id_modello 
INNER JOIN dbo.MACCHINE_TIPOLOGIE T ON I.id_tipologia = T.id_tipologia 
INNER JOIN dbo.VIEW_CANTIERI V ON M.id_cantiere = V.id_cantiere 
INNER JOIN dbo.MACCHINE_PRODUTTORI P ON I.id_produttore = P.id_produttore 
INNER JOIN dbo.CLIENTI C ON V.id_cliente = C.id_cliente 
OUTER APPLY (SELECT TOP (1) 
       MA.data_fine, 
       DATEDIFF(day, MA.data_fine, GETDATE()) AS data_diff 
      FROM dbo.MANUTENZIONI AS MA 
      WHERE MA.id_macchina = M.id_macchina 
      ORDER BY MA.data_fine DESC) MA 
WHERE M._del = 'N' 
+0

ありがとう、これはSQL Server 2008で素晴らしいです! – Leitmotif

2

謝罪あなたはすでにこれをやったが、私はあなたがそれらを持っている場合SHOWPLAN(CTRL + L)、またはパフォーマンス・ツールを使用することをお勧めします。ボトルネックは、例えばジョインの1つ、欠落した索引、または悪い実行計画を促進する古い統計である可能性があります。

ビューが書き込まれるよりもはるかに頻繁に読み込まれる場合、または正確に最新のデータを保持する必要がない場合(つまり、毎日結果をキャッシュして昨夜の更新からビューを読み取る場合)インデックス付きビューの使用を検討してください。これはビューをテーブルのようにキャッシュするため、テーブルから読み込むたびに(CASEとJOINの両方を含む)操作は実行されません(インデックスの使用速度も速くなります)。また、最近のデータだけが変更された場合は、日付のインデックス付きビューを分割することもできます。

+0

お寄せいただきありがとうございます:私はインデックス付きのビューを使用することを考えます、私はリアルタイムの更新の必要はありませんので、それは良い改善する必要があります! – Leitmotif

関連する問題