表达式中的类型转换可能会影响“CardinalityEstimate”——在计算列上?

Mar*_*lli 5 sql-server optimization sql-server-2016 computed-column cardinality-estimates

我看了一下这个问题:

表达式中的类型转换可能会影响查询计划选择中的“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))
Run Code Online (Sandbox Code Playgroud)

当我运行以下查询时,我在选择时收到警告: 查询计划在这里

表达式中的类型转换 (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
Run Code Online (Sandbox Code Playgroud)

当我从选择中删除 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
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

有什么办法可以摆脱这个警告吗?

它是一个持久化的列,转换已经完成,为什么查询优化器会继续处理它?

Pau*_*ite 7

我看了一下这个问题:

表达式中的类型转换可能会影响查询计划选择中的“CardinalityEstimate”?

但这与整理有关,而不是与计算列有关。

这是同样的问题。该警告是信息性的,可帮助您了解基数估计时可能会注意到的任何问题。

有什么办法可以摆脱这个警告吗?

它是一个持久化的列,转换已经完成,为什么查询优化器会继续处理它?

仅仅因为计算列是持久化的,并不意味着优化器会选择使用持久化的值。SQL Server 会在编译过程开始时例行地将计算列(持久性或非持久性)扩展到基础定义中。稍后,它可能会也可能不会将表达式匹配回可用的持久计算列。当优化器遇到表达式时,它可能会向计划添加警告。

防止这种扩展和匹配的唯一方法是在合适的版本上启用跟踪标志 176

当我从选择中删除MINMAX列时,不再有任何警告

通过此更改,优化器能够简化查询以删除不必要的连接。结果是一个TRIVIAL计划,没有基于成本的选择,所以没有关于计划选择的警告。