【发布时间】:2019-04-06 05:27:59
【问题描述】:
在 SQL Server 2017 开发人员版上运行。
我有一个简单的案例,我试图获取两个 INT 列并将它们连接成一个名为“NUMVER”的列,用分号分隔。尽管我可以重构应用程序中的内容以不同方式执行此操作,但如果可以不重构并更改语法以使其不会引发“!”,将会很有趣。执行计划中的警告。
详情:
名为“DOCS”的表具有列 NUM 和 VER,它们都是 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并添加了一些插入语句。
【问题讨论】:
-
无法复制问题,我已根据给定信息创建了表格,但没有警告我。如果您可以制作测试用例,我们可以帮助您。
-
您的查询是否过于简化?您的真实查询中有
WHERE吗?此外,您应该养成声明数据类型的长度、比例和精度的习惯。不这样做会给你一些(讨厌的)惊喜。 -
UsmanMirza 和 Lamu:针对您的 cmets,我在原始问题中添加了更多细节。感谢您的宝贵时间。
-
我个人建议在你的情况下使用computed (virtual) columns。
标签: sql-server sql-execution-plan