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)
有什么办法可以摆脱这个警告吗?
它是一个持久化的列,转换已经完成,为什么查询优化器会继续处理它?
我看了一下这个问题:
表达式中的类型转换可能会影响查询计划选择中的“CardinalityEstimate”?
但这与整理有关,而不是与计算列有关。
这是同样的问题。该警告是信息性的,可帮助您了解基数估计时可能会注意到的任何问题。
有什么办法可以摆脱这个警告吗?
它是一个持久化的列,转换已经完成,为什么查询优化器会继续处理它?
仅仅因为计算列是持久化的,并不意味着优化器会选择使用持久化的值。SQL Server 会在编译过程开始时例行地将计算列(持久性或非持久性)扩展到基础定义中。稍后,它可能会也可能不会将表达式匹配回可用的持久计算列。当优化器遇到表达式时,它可能会向计划添加警告。
防止这种扩展和匹配的唯一方法是在合适的版本上启用跟踪标志 176。
当我从选择中删除
MIN
和MAX
列时,不再有任何警告
通过此更改,优化器能够简化查询以删除不必要的连接。结果是一个TRIVIAL
计划,没有基于成本的选择,所以没有关于计划选择的警告。