Tsql 两个varchar之间的T-SQL隐式转换

Tsql 两个varchar之间的T-SQL隐式转换,tsql,implicit-conversion,Tsql,Implicit Conversion,我继承了一些T-SQL(SQL Server 2008),并试图找出一些查询运行速度非常慢的原因。在实际执行计划中我有三个聚集索引扫描,分别花费了19%、21%和26%,因此这似乎是我问题的根源 字段的内容通常为数字(但某些职务编号有字母前缀) 数据库设计(供应商提供)非常差。在他们的应用程序中,作业编号的最大长度为12个字符,但在连接的表中,它在某些位置被定义为varchar(50),在其他位置被定义为varchar(15)。我的参数是varchar(12),但如果我将其更改为varchar(

我继承了一些T-SQL(SQL Server 2008),并试图找出一些查询运行速度非常慢的原因。在
实际执行计划中
我有三个聚集索引扫描,分别花费了19%、21%和26%,因此这似乎是我问题的根源

字段的内容通常为数字(但某些职务编号有字母前缀)

数据库设计(供应商提供)非常差。在他们的应用程序中,作业编号的最大长度为12个字符,但在连接的表中,它在某些位置被定义为
varchar(50)
,在其他位置被定义为
varchar(15)
。我的参数是
varchar(12)
,但如果我将其更改为
varchar(50)

该节点包含以下内容:

Predicate: [Live_Costing].[dbo].[TSTrans].[JobNo] as [sts1].[JobNo]=CONVERT_IMPLICIT(varchar(50),[@JobNo],0)
sts1
是一个派生表,但它从中提取的
jobno
是一个
varchar(50)

我不明白为什么它在两个varchar之间进行隐式转换。只是因为它们的长度不同吗

我对执行计划相当陌生

有没有一种简单的方法可以确定exec计划中的哪个节点与查询的哪个部分相关? 谓词是join子句吗

问候


标记

某些变量可以具有排序规则:

不管怎样,您都需要验证排序规则,可以在服务器、数据库、表和列级别指定排序规则

首先,检查tempdb和供应商提供的数据库之间的排序规则。应该匹配。如果没有,它将倾向于进行隐式转换

假设您无法修改供应商提供的代码库,以下一项或多项应能帮助您: 1) 预定义temp表,并为key字段指定与正在使用的db中相同的排序规则,而不是tempdb。 2) 在进行字符串比较时提供排序规则。 3) 如果对临时表使用“select into”,请为键值指定排序规则 4) 确保表和列的排序规则与数据库排序规则匹配(如果仅将供应商的特定表导入现有数据库,则这一点非常重要。)

如果您可以更改供应商提供的代码库,我建议您检查使所有char键长度相同而不是varchar的成本。Varchar的开销为10。需要注意的是,如果您创建的固定长度字符字段不为null,它将被填充到右侧(不可避免)

理想情况下,您应该使用int键,并且仅使用varchar字段进行用户交互/查找:

创建表产品(ProductID int not null identity(1,1)主键群集,ProductNumber varchar(50)not null)

alter table Products添加约束uckProducts\U ProductNumber unique(ProductNumber)

然后在ProductID上执行所有连接,而不是ProductNumber。只需过滤ProductNumber即可


很好。

。虽然转换发生在参数而不是列上,但这看起来并不是问题的原因。好吧,为了给你一个公正的答案,需要更多的信息。也许你能给我们更多关于执行计划的细节?也许你可以在某处发布一些图片或xml?这是一个巨大的查询。我会发布exec计划,但如果我编辑帖子,似乎没有办法添加附件(我可以找到)。当你编辑帖子时,你可以添加一个图像:)当你说“sts1”是一个派生表时,这是在嵌套的select中吗?如果是这样,为什么谓词在连接上而不是嵌套的select/CTE中?要求SQL将所有数据放入派生表,然后要求它在派生表之外执行筛选(除非数据有其他用途?)似乎有点奇怪,这有助于查看SQL本身。