星期六, 5月 09, 2020

[SQL] UNION ALL 發生隱含轉換 2

以前遇到的隱含式轉換都跟資料型別轉換有直接轉換關係,EX:char 轉為 int、bit 轉為 int,但這次是型別沒有變化,是型別大小造成的隱含式轉換 char(11) 被轉為 char(16)

在 TempDB 內建立 tblMaster、tblDetail1、tblDetail2 來模擬實務情況,這三個 Table 都只有一個 NO 欄位,只有 tblDetail2 是開 char(11),其他兩個 Table 都是 char(16)

CREATE TABLE [dbo].[tblMaster]
(
  [NO16] [char](16) NOT NULL, -- char(16)
  CONSTRAINT [PK_tblMaster] PRIMARY KEY CLUSTERED ([NO16] ASC)
)
GO

CREATE TABLE [dbo].[tblDetail1]
(
  [NO16] [char](16) NOT NULL, -- char(16)
  CONSTRAINT [PK_tblDetail] PRIMARY KEY CLUSTERED([NO16] ASC)
)
GO

CREATE TABLE [dbo].[tblDetail2]
(
  [NO11] [char](11) NOT NULL, -- char(11)
  CONSTRAINT [PK_tblDetail2] PRIMARY KEY CLUSTERED([NO11] ASC)
)
GO

模擬實務上 TSQL 語法並觀察執行計畫
SELECT *
FROM tblMaster AS M
  JOIN
    (
      SELECT
        [NO16] AS [NO]
      FROM tblDetail1
      UNION ALL
      SELECT 
        [NO11]
      FROM tblDetail2
    ) AS D ON M.[NO16] = D.[NO]

從執行計畫中可以看出,tblDetail1 是 Index Seek [綠框]、tblDetail2 是 Index Scan [紅框] 來搜尋資料

[SQL] UNION ALL 發生隱含轉換 2-1

SELECT 操作子內的警告

[SQL] UNION ALL 發生隱含轉換 2-2

tblDetail2 Predicate 關於隱含轉換的訊息

[SQL] UNION ALL 發生隱含轉換 2-3

另外測試兩種情況,想驗證看看是否會發生隱含轉換,結論:不會有隱含轉換

測試一:直接對 tblDetail1 和 tblDetail2 UNION ALL
SELECT
  [NO16]
FROM tblDetail1
UNION ALL
SELECT 
  [NO11]
FROM tblDetail2

[SQL] UNION ALL 發生隱含轉換 2-4

測試二:tblMaster 直接和 tblDetail2 JOIN

SELECT *
FROM tblMaster AS M
  JOIN tblDetail2 AS D ON M.[NO16] = D.[NO11]

[SQL] UNION ALL 發生隱含轉換 2-5

以上模擬和測試跟實務結果是一致,記錄一下

沒有留言:

張貼留言