链接服务器查询中的参数从 varchar 转换为 nvarchar,导致索引扫描和性能不佳

2024-01-04

我们有以下设置:

  • 源服务器版本 12 或 15,排序规则 Latin1_General_CI_AS(在我们的责任范围内,我们可以更改此处的所有内容)
  • 链接服务器版本 13,排序规则:Latin1_General_CI_AS(不属于我们的责任,我们无法在此处更改任何内容)
  • 链接数据库排序规则:SQL_Latin1_General_CP1_CI_AS
  • NHibernate 用作 ORM 来创建查询(这意味着:灵活性较低),仅对链接服务器上的表进行很少的查询。
  • 链接服务器选项: sp_addlinkedserver @server = N'MyLinkedServer', @srvproduct=N'SQL Server'

    '排序规则兼容='假', '数据访问='true', '距离='假', 'pub='假', 'rpc='假', 'rpc 输出='假', '子='假', '连接超时='0', '排序规则名称=ull, '惰性模式验证='false', '查询超时='0', '使用远程排序规则='true', '远程进程交易提升='true'

目标表链接服务器上的目标表列看起来像这样:

PrimaryKey varchar(23)
OtherThing varchar(42)

我们发出这样的查询:

SELECT OtherThing FROM TargetTableOnLinkedServer WHERE PrimaryKey = 'Hello World'

我们也尝试与sp_execute参数为 varchar(8000) - 下面有更详细的查询。

在 SQL Server Profiler 中,我们看到链接查询基本上被转换为:

SELECT OtherThing FROM TargetTableOnLinkedServer WHERE PrimaryKey = N'Hello World'

请注意这里的“N”。 “N”(如 Nvarchar 中的)导致索引扫描,而不是索引查找。 不幸的是,我们找不到抑制N的方法,也不知道原因。

有没有办法防止“链接服务器机制”将参数“转换”为 unicode 字符串(通过添加 N)。

提前致谢!


更详细的查询:

SELECT MyColumn FROM MyLinkedServer.MyDatabase.dbo.MyTable A WHERE A.MyColumn = 'MyValue'

这会导致探查器 SP:StmtCompleted 事件在链接服务器上

SELECT "Tbl1001"."MyColumn" "Col1003" FROM "MyDatabase"."dbo"."MyTable" "Tbl1001" WHERE "Tbl1001"."MyColumn"=N'MyValue'

以及 RPC:Completed 事件:

declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,NULL,N'SELECT "Tbl1001"."MyColumn" "Col1003" FROM "MyDatabase"."dbo"."MyTable" "Tbl1001" WHERE "Tbl1001"."MyColumn"=N''MyValue'''
select @p1

NHibernate 创建如下查询:

EXEC sp_executesql N'SELECT MyColumn FROM MyLinkedServer.MyDatabase.dbo.MyTable A WHERE A.MyColumn = @p1',N'@p1 varchar(8000)', @p1='MyValue'

请注意 varchar 和缺少“N”。 这会导致以下查询带有索引扫描(至少这显示了我在 SMSS 中复制粘贴查询时的执行计划):

declare @p1 int
exec sp_prepexec @p1 output,N'@P1 nvarchar(4000)',N'SELECT "Tbl1001"."MyColumn" "Col1004" FROM "MyDatabase"."dbo"."MyTable" "Tbl1001" WHERE "Tbl1001"."MyColumn"=@P1',N'MyValue'
select @p1

正确的做法是使用索引查找:

exec sp_prepexec @p1 output,N'@P1 varchar(4000)',N'SELECT "Tbl1001"."MyColumn" "Col1004" FROM "MyDatabase"."dbo"."MyTable" "Tbl1001" WHERE "Tbl1001"."MyColumn"=@P1','MyValue'
select @p1

我还尝试使用另一个提供程序 MSOLEDBSQL(显然是最现代的),没有任何变化:

EXEC master.dbo.sp_addlinkedserver @server = N'MyServer', @srvproduct=N'', @provider=N'MSOLEDBSQL', @provstr=N'Server=MyServerName'

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

链接服务器查询中的参数从 varchar 转换为 nvarchar,导致索引扫描和性能不佳 的相关文章

随机推荐