串联INT列警告:表达式中的类型转换导致执行计划中的CardinalityEstimate警告

时间:2019-04-06 05:28:00

标签: sql-server sql-execution-plan

在SQL Server 2017 Developer Edition上运行。

我有一个简单的情况,我尝试获取两个INT列并将它们连接到一个用分号分隔的称为“ NUMVER”的列中。尽管我可以重构应用程序中的内容来以不同的方式执行此操作,但是很有趣的是,知道是否有可能不重构并更改语法,从而不会引发“!”。执行计划中的警告。

详细信息:

一个名为“ DOCS”的表包含列NUMVER,它们都是INT加上PK:

CREATE TABLE [dbo].[DOCS2](
    [DOCS_ID] [int] IDENTITY(1,1) NOT NULL,
    [NUM] [int] NOT NULL,
    [VER] [int] NOT NULL,
 CONSTRAINT [PK_DOCS] PRIMARY KEY CLUSTERED ([DOCS_ID] ASC)
)
GO

一些数据:

INSERT INTO dbo.DOCS (NUM, VER) VALUES (1,1);
INSERT INTO dbo.DOCS (NUM, VER) VALUES (2,1);

我想用分号分隔符将NUM和VER选择到单列NUMVER中:

SELECT CAST(NUM AS varchar(20)) + ';' + CAST(VER AS varchar(20)) AS "MENU" FROM DOCS;

返回的结果很好,我得到“ 1; 1或“ 2; 1”等。但是我收到执行计划的警告:

  

表达式中的类型转换(CONVERT(varchar(20),[mydb]。[dbo]。[DOCS]。[NUM],0))可能会影响查询计划选择中的“ CardinalityEstimate”,表达式中的类型转换(CONVERT (varchar(20),[mydb]。[dbo]。[DOCS]。[VER],0))可能会影响查询计划选择中的“ CardinalityEstimate”

上面的示例是一个更复杂,非常繁忙的表的简化示例,如果这是微不足道的警告,那么我继续,但是我很想得到“!”尽可能消失吗?

注意:我没有观察到性能问题,我只是在积极主动(或者过于好奇和谨慎)。

注意2:为清楚起见,我添加了有关该场景的更多详细信息,例如创建表DDL并添加了一些插入语句。

1 个答案:

答案 0 :(得分:1)

有效词是 may 。在这种情况下,这不会影响基数估计,因为该列只是选中的,不会在可能影响估计的任何过滤或分组操作中使用。

有一个 连接项“ Microsoft在SQL2012中表达了新类型转换。....警告,对实际使用而言太吵了”

  

我明白你的意思了。尽管我同意在大多数情况下这是噪音,   解决这个问题的优先级较低。如果我们得到更多,我们将研究它   反馈。现在,我已经设计关闭了

当连接关闭时,这丢失了。 UserVoice site here也有类似的投诉。

  

当转换/广播的列只是简单的时候,这似乎是一个超范围   在选定/预计的列列表中引用,而根本不在   过滤子句。

可以跳过一些箍以摆脱它。例如

SELECT FORMAT(NUM, 'N0') + ';' + FORMAT(VER, 'N0') 
FROM [DOCS2];

但是我不建议这样做。 FORMAT有其自身的问题(与性能有关),而应用不必要的FORMAT会使代码的可读性降低。