这些参数在我的 SQL Server 查询计划开始时意味着什么?

Ste*_*__T 2 sql-server jdbc

我正在查看 SQL Server Mgmt Studio 中的查询计划,我看到如下内容:

(@P0 nvarchar(4000), @P1 nvarchar(4000)) Update...
Run Code Online (Sandbox Code Playgroud)

参数旁边的类型是什么意思?对于此示例,我们假设这些参数的列实际上是varchar(64). 这是在运行时绑定参数的方式吗?

编辑

这是一个使用 JDBC 3.0 或 4.0 提供程序的 Java EE 应用程序。基本上我们有一个充满 SQL 语句的属性文件,如下所示:

mySqlStatementFoo = UPDATE Schema.Table.Column set column = 1 WHERE objectID = ?
Run Code Online (Sandbox Code Playgroud)

看起来在过去,如果存在绑定不匹配,我们会像这样转换参数:

Where objectID = CAST(? AS VARCHAR(36))
Run Code Online (Sandbox Code Playgroud)

我想他们选择这样做是因为我们支持多个数据库。IE DB2 和 Oracle。我还没有看到实际的 Java,但我怀疑他们只是从文件中选择语句并将其发送到网络中。我在做负载测试,看到我们在做表扫描,怀疑优化器没有使用正确的索引,因为参数绑定不正确。

Aar*_*and 6

是的,由于 SQL Server 必须做出的猜测,您可能会看到隐式转换。它正在创建一个计划,该计划不仅适用于您现在传递的参数值,还适用于其他潜在值。对于字符串,它(或者也许是 JDBC?不确定)选择 4000 和 Unicode 的任意默认值。我相信 JDBC 中有一些方法可以发送 Unicode(Unicode 与非 Unicode 隐式转换是最乏味的),但是您仍然要处理长度问题(这可能是也可能不是您的问题)具体情况;同样,不确定)。

为了避免隐式转换和猜测,以及最终的扫描和高 CPU 条件,您需要通过显式/强类型让 SQL Server 了解参数中使用的数据类型。

以下是我的建议,按优先顺序排列:

  1. 切换到存储过程。
  2. 切换到存储过程。
  3. 明确声明您的变量,例如:

    DECLARE @p1 VARCHAR(36) = ?; UPDATE ... WHERE col = @p1;
    
    Run Code Online (Sandbox Code Playgroud)
  4. 继续使用CAST/ CONVERT

  • @马丁是的,他们是。 (2认同)
  • @MartinSmith http://www.diggingforfire.net/fightclub/ ;-) (2认同)