Sql-Server

表達式中的類型轉換可能會影響“CardinalityEstimate” - 在計算列上?

  • August 31, 2019

我看了一下這個問題:

表達式中的類型轉換可能會影響查詢計劃選擇中的“CardinalityEstimate”?

但這與排序規則有關,與計算列無關。

我在下面的查詢中使用了以下表定義,這給了我一個查詢提示

表達式中的類型轉換 (CONVERT(varchar(10),

$$ t $$.$$ FLTCD_FLT_DATE $$,112)) 可能會影響查詢計劃選擇中的“CardinalityEstimate”

在此處輸入圖像描述

請注意計算列flightReference

CREATE TABLE [dbo].[repl_Transportation] ( 
[FLIGHT#]          INT                              NOT NULL,
[FLTCD_FLT_DATE]   DATETIME                             NULL,
[FLTCD_DEP_GATE]   CHAR(3)                              NULL,
[FLTCD_ARR_GATE]   CHAR(3)                              NULL,
[FLTCD_SEQUENCE]   CHAR(1)                              NULL,
[DIRECTION]        CHAR(1)                              NULL,
[PNR_NUMBERS]      VARCHAR(70)                          NULL,
[HK]               NUMERIC(3,0)                         NULL,
[Create_Date]      DATETIME                         NOT NULL,
[Modify_Date]      DATETIME                             NULL,
[flightReference]  AS (substring(((CONVERT([varchar](10),[FLTCD_FLT_DATE],
(112))+[FLTCD_DEP_GATE])+[FLTCD_ARR_GATE])+[FLTCD_SEQUENCE],(3),(13))) PERSISTED,
CONSTRAINT   [PK_FLIGHT#]  PRIMARY KEY CLUSTERED    ([FLIGHT#] asc))



IF OBJECT_ID('[dbo].[repl_Transportation_Details]') IS NOT NULL 
DROP TABLE [dbo].[repl_Transportation_Details] 
GO
CREATE TABLE [dbo].[repl_Transportation_Details] ( 
[FLT_LEG_ID]     INT                              NOT NULL,
[FLIGHT#]        INT                              NOT NULL,
[LEG_NO]         TINYINT                              NULL,
[AIRLINE_CODE]   CHAR(2)                              NULL,
[AIRLINE_FLTNO]  VARCHAR(6)                           NULL,
[DEP_DATE_TIME]  DATETIME                             NULL,
[ARR_DATE_TIME]  DATETIME                             NULL,
[DEP_AIRPORT]    CHAR(3)                              NULL,
[ARR_AIRPORT]    CHAR(3)                              NULL,
[Create_Date]    DATETIME                             NULL,
[Modify_Date]    DATETIME                             NULL,
CONSTRAINT   [PK_FLT_LEG_ID]  PRIMARY KEY CLUSTERED    ([FLT_LEG_ID] asc))

當我執行以下查詢時,我在選擇時收到警告: 查詢計劃在這裡

表達式中的類型轉換 (CONVERT(varchar(10),

$$ t $$.$$ FLTCD_FLT_DATE $$,112)) 可能會影響查詢計劃選擇中的“CardinalityEstimate”

   SELECT  t.FLIGHT#,
   t.flightReference,
   PNR_NUMBERS,
   MIN(td.DEP_DATE_TIME)     AS departDate,
   MAX(td.ARR_DATE_TIME)     AS arrivalDate,
   CASE WHEN 
    PNR_NUMBERS IS NULL OR PNR_NUMBERS = '' 
    THEN 'Paper Ticket' 
    ELSE 'E-Ticket' 
   END          AS ticketType,
   'US'         AS source,
   0          as sourceId,
   DIRECTION,
   FLTCD_DEP_GATE,
   FLTCD_ARR_GATE
FROM        repl_Transportation      AS t 
LEFT JOIN repl_Transportation_Details    AS td ON td.FLIGHT# = t.FLIGHT#
GROUP BY t.FLIGHT#, 
   t.flightReference, 
   PNR_NUMBERS,
   DIRECTION,
   FLTCD_DEP_GATE,
   FLTCD_ARR_GATE

當我從選擇中刪除 MIN 和 MAX 列時,不再有任何警告,查詢計劃在這裡

   SELECT  t.FLIGHT#,
   t.flightReference,
   PNR_NUMBERS,
   --MIN(td.DEP_DATE_TIME)     AS departDate,
   --MAX(td.ARR_DATE_TIME)     AS arrivalDate,
   CASE WHEN 
    PNR_NUMBERS IS NULL OR PNR_NUMBERS = '' 
    THEN 'Paper Ticket' 
    ELSE 'E-Ticket' 
   END          AS ticketType,
   'US'         AS source,
   0          as sourceId,
   DIRECTION,
   FLTCD_DEP_GATE,
   FLTCD_ARR_GATE
FROM        repl_Transportation      AS t 
LEFT JOIN repl_Transportation_Details    AS td ON td.FLIGHT# = t.FLIGHT#
GROUP BY t.FLIGHT#, 
   t.flightReference, 
   PNR_NUMBERS,
   DIRECTION,
   FLTCD_DEP_GATE,
   FLTCD_ARR_GATE

在此處輸入圖像描述

有什麼辦法可以擺脫這個警告嗎?

它是一個持久列,轉換已經完成,為什麼查詢優化器還在繼續呢?

我看了一下這個問題:

表達式中的類型轉換可能會影響查詢計劃選擇中的“CardinalityEstimate”?

但這與排序規則有關,與計算列無關。

這是同一個問題。該警告是資訊性的,可幫助您了解在基數估計中可能注意到的任何問題。

有什麼辦法可以擺脫這個警告嗎?

它是一個持久列,轉換已經完成,為什麼查詢優化器還在繼續呢?

僅僅因為計算列是持久化的,並不意味著優化器會選擇使用持久化的值。SQL Server 例行地在編譯過程開始時將計算列(持久或不持久)擴展為基礎定義。稍後,它可能會將表達式匹配回可用的持久計算列,也可能不匹配。當優化器遇到表達式時,它可能會在計劃中添加警告。

防止這種擴展和匹配的唯一方法是在合適的版本上啟用跟踪標誌 176 。

當我從選擇中刪除MINMAX列時,不再有任何警告

通過此更改,優化器能夠簡化查詢以刪除不必要的連接。結果是一個TRIVIAL計劃,沒有基於成本的選擇,因此沒有關於計劃選擇的警告。

引用自:https://dba.stackexchange.com/questions/203897