星期日, 8月 05, 2018

[SQL] UNION ALL 一定會讀出全部資料?

平常跟同事討論時,都會說,SQL Server 是 Cost Base,不是 Rule Base,Query Optimizer 會去找出最低成本執行計畫來執行,所以效能議題,一定要開啟 Statistics IO,Time、執行計畫和執行計畫成本來判斷,不要看 TSQL 語法就在那臆測效能如何,不過講歸講,自己對於使用 UNION ALL 會讀出全部資料後似乎也堅信不移,不知道哪來的觀念,Orz

調校遇上使用到 UNION ALL 語法,調校前 (使用 5 次) 後 (使用 3 次) 都沒有因為 UNION ALL 關係導致讀出全部資料來操作

改善後語法
SELECT
  ..................
FROM
  (
    SELECT
      ..................
    FROM 出貨檔頭
    WHERE
      ..................
    UNION ALL
    SELECT
      ..................
    FROM 出貨檔頭 AS R
      JOIN 
        (
          SELECT
            ..................
          FROM 客戶
        ) AS w1 ON r.客戶編號 = w1.客戶編號
                  AND (r.date BETWEEN w1.起始日期 AND w1.結束日期)
    WHERE
      .................. 
  ) AS T
  JOIN vw客戶 AS c1 ON T.CustNO = c1.CustNO
  JOIN 
  (
    SELECT
      ..................
    FROM 出貨 AS t
    UNION ALL 
    SELECT
      ..................
    FROM 退貨 AS t 
    UNION ALL 
    SELECT
      ..................
    FROM 庫存出貨 AS t
  ) AS p ON T.out_id = p.out_id
  JOIN 訂單 AS F ON P.訂單編號 = F.訂單編號
從下面執行計畫部分截圖,就可以發現啦,是利用 Nested Loops 一筆一筆進 UNION ALL 內的每一個 Table 內把資料找出來,最後再 UNION ALL 後傳出
然後很無聊的把第 25 行的 JOIN 改為 LEFT JOIN,想說會不會因此就讀出全部資料 UNION ALL 後才會去進行比對,執行計劃也沒有變化,^^''

自己的迷思自己來打破,還是要觀察執行計劃才會知道 TSQL 是如何執行的

沒有留言:

張貼留言