2013-02-20 88 views
0

我需要從數據庫中獲取所有運行,但需要標記是否存在此運行的錯誤。使用3個表優化TSQL查詢

3表:

  • 上運行:包含運行)
  • Runfiles:包含一個運行期間處理
  • 消息全部文件ID:包含錯誤,警告,...

此查詢是否可以進一步優化?

SELECT TOP 1000 runid, 
      start, 
      end, 
      userid, 
      CASE 
       WHEN EXISTS(SELECT rf.fk_fileid 
          FROM runfiles rf 
          WHERE rf.fk_runid = r.runid 
           AND EXISTS(SELECT m.messageid 
              FROM messages m 
              WHERE m.fk_fileid = 
                rf.fk_fileid 
                AND m.fk_statusid = 4)) 
      THEN 1 
       ELSE 0 
      END     AS ContainsError 
FROM runs r 
ORDER BY start DESC 

請不要評論表名稱,他們被翻譯爲這個問題。

謝謝!

+0

看執行計劃並添加適當的索引 – Magnus 2013-02-20 14:58:04

+0

「優化」是什麼意思?如果您詢問性能,那麼您應該在查詢中包含執行計劃。如果您問的是提高可讀性或可維護性,那麼[代碼評論網站](http://codereview.stackexchange.com/)將是一個更好的問題。 – Pondlife 2013-02-20 16:21:07

+0

有時你只需要比較不同的選項。你有沒有試過在運行文件和消息上的左連接? – Narnian 2013-02-20 17:19:23

回答

0

試試這個:在選擇列表

SELECT TOP 1000 
    r.runid 
    ,r.start 
    ,r.[end] 
    ,r.userid 
    ,CASE WHEN m.messageid IS NOT NULL THEN 1 ELSE 0 END AS ContainsError 
FROM runs r 
LEFT JOIN runfiles rf 
    ON rf.fk_runid = r.runid 
LEFT JOIN [messages] m 
    ON m.fk_fileid = rf.fk_fileid 
    AND m.fk_statusid = 4 
ORDER BY r.start DESC 

什麼是跑在結果集中的每一行。這意味着CASE語句中的嵌套子查詢正在爲這些TOP 1000行中的每一行執行。

使用左連接和CASE語句來檢查主鍵是否允許將整個語句作爲一個集合進行評估,該SQL Server的內置操作是基於該集合進行的。它應該以更好的方式執行。

+0

關係Run <-> RunFile是一對多關係Runfile <->消息也是一對多的。因此,該查詢將多次返回相同的運行。也許有一種方法可以限制連接中結果的數量。我會研究它。謝謝! – Nullius 2013-02-21 06:32:53