为什么`nvarchar`参数比'text'`SqlCommand`命令的其他类型更快?

Ken*_*itt 5 c# sql-server

概观

这个问题是这个问题的一个更具体的版本:

但我注意到其他数据类型的性能相同(事实上,在我的情况下,我根本没有使用任何bigint类型).

以下是一些其他问题似乎应该涵盖这个问题的答案,但我观察的是他们所指出的相反的问题:

上下文

我有一些C#代码用于将数据插入表中.代码本身是数据驱动的,因为一些其他数据指定了应该插入数据的目标表.所以,我可以在存储过程中使用动态SQL,我选择在我的C#应用​​程序中生成动态SQL.

对于第I行插入,命令文本始终相同,因此在插入任何行之前,我会生成一次.命令文本的格式如下:

INSERT SomeSchema.TargetTable ( Column1, Column2, Column3, ... )
VALUES ( SomeConstant, @p0, @p1, ... );
Run Code Online (Sandbox Code Playgroud)

对于每个插入,我创建一个SqlParameter对象数组.

对于' nvarchar'行为,我只是使用SqlParameter(string parameterName, object value)构造函数方法,而不是显式设置任何其他属性.

对于"简并的行为,我所用的SqlParameter(string parameterName, SqlDbType dbType)构造方法,并且还设定Size,PrecisionScale特性适当.

对于这两个版本的代码,传递给构造函数方法或单独分配给Value属性的值的类型为object.

' nvarchar'版本的代码大约需要1-1.5分钟."退化"或"特定类型"代码需要超过9分钟; 所以慢了6-9倍.

SQL Server Profiler没有透露任何明显的罪魁祸首.特定于类型的代码生成看起来更好的SQL,即动态SQL命令,其参数包含适当的数据类型和类型信息.

假设

我怀疑,因为我传递了一个object类型值作为参数值,ADO.NET SQL Server客户端代码在生成并向SQL Server发送命令之前正在转换,转换或以其他方式验证该值.我很惊讶,从nvarcharSQL Server必须执行的每个相关目标表列类型的转换比客户端代码所做的快得多.

笔记

我知道这SqlBulkCopy可能是插入大量行的最佳选择,但我更好奇为什么' nvarchar'的情况超出'特定于类型'的情况,而且我当前的代码足够快就像给定它经常处理的数据量.

Ber*_*sch 0

答案确实取决于您正在运行的数据库,但它与字符编码过程有关。SQL Server 引入了 NVarChar 和 NText 字段类型来处理 UTF 编码数据。UTF 也恰好是 .NET CLR 的内部字符串表示形式。NVarChar 和 NText 不必转换为另一种字符编码,这需要很短但可测量的时间。

其他数据库允许您在数据库级别定义字符编码,而其他数据库则允许您逐列定义它。性能差异实际上取决于驱动程序。

还需要注意的是:

  • 使用准备好的语句插入会强调转换为数据库内部格式的效率低下
  • 这与数据库查询字符串的效率无关 - UTF-16 比 Text 和 VarChar 的默认 Windows-1252 编码占用更多空间。
  • 当然,在全局应用中,UTF支持是必要的