我正在查看 SQL Server Mgmt Studio 中的查询计划,我看到如下内容:
(@P0 nvarchar(4000), @P1 nvarchar(4000)) Update...
参数旁边的类型是什么意思?对于此示例,我们假设这些参数的列实际上是varchar(64)
. 这是在运行时绑定参数的方式吗?
编辑
这是一个使用 JDBC 3.0 或 4.0 提供程序的 Java EE 应用程序。基本上,我们有一个充满 SQL 语句的属性文件,如下所示:
mySqlStatementFoo = UPDATE Schema.Table.Column set column = 1 WHERE objectID = ?
过去,如果存在绑定不匹配,我们会像这样转换参数:
Where objectID = CAST(? AS VARCHAR(36))
我想他们选择这样做是因为我们支持多个数据库。IE DB2 和 Oracle。我还没有看到实际的 Java,但我怀疑他们只是从文件中选择语句并将其发送到网络中。我正在做负载测试,看到我们正在做表扫描,并怀疑优化器没有使用正确的索引,因为参数绑定不正确。
是的,由于 SQL Server 必须做出的猜测,您可能会看到隐式转换。它正在创建一个计划,该计划不仅适用于您现在传递的参数值,还适用于其他潜在值。对于字符串,它(或者可能是 JDBC?不确定)选择任意默认值 4000 和 Unicode。我相信 JDBC 中有一些方法可以不发送 Unicode(Unicode 与非 Unicode 隐式转换是最乏味的),但是您仍然要处理长度问题(这可能是也可能不是您的问题具体情况;同样,不确定)。
为了避免隐式转换和猜测,以及最终的扫描和高 CPU 条件,您需要通过显式/强类型让 SQL Server 了解参数中使用的数据类型。
以下是我的建议,按优先顺序排列:
明确声明你的变量,例如:
继续使用
CAST
/CONVERT
。