MaxLength及其如何影响查询

xsl*_*xsl 5 sql sql-server performance entity-framework nvarchar

我正在使用Entity Framework 4.3.1,代码优先,我正在查看正在生成的查询的SQL事件探查器.这是一个例子:

正如您所看到的 - 它指定了参数,nvarchar(max)但在我的配置中,我指定了一个MaxLength值.因此,我希望参数将作为参数传递.nvarchar(n) 因为它没有这样做,我们发现查询运行缓慢,这个简单的更改会加快它们的速度.

有谁知道我们如何说服实体框架生成正确的nvarchar长度?

这是我的实体和配置代码:

实体

public class StorageTransportOrderItem 
{
    public string StorageTransportOrderItemNumber { get; set; }
    public string StorageNumber { get; set; }
    [...]
}
Run Code Online (Sandbox Code Playgroud)

组态

ToTable("StorageTransportOrderItem");

Property(p => p.StorageTransportOrderNumber)
    .HasMaxLength(10);
Property(d => d.StorageTransportOrderItemNumber)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
    .HasMaxLength(4);

HasKey(d => new
{
    d.StorageTransportOrderItemNumber,
    d.StorageNumber,
    d.StorageTransportOrderNumber
 });
Run Code Online (Sandbox Code Playgroud)

示例查询

FROM [dbo].[StorageTransportOrder] AS [Extent1]
WHERE ([Extent1].[StorageNumber] = @p__linq__0) AND ([Extent1]
[StorageTransportOrderNumber] = @p__linq__1)
)  AS [Limit1]',N'@p__linq__0 nvarchar(max) ,@p__linq__1 nvarchar(max)  
',@p__linq__0=N'200',@p__linq__1=N'0001374850'
Run Code Online (Sandbox Code Playgroud)

请注意nvarchar(max),这是使它变慢的原因.

kmp*_*kmp 3

Tl:博士;我认为HasMaxLength(),或者事实上,您在使用Entity Framework时可以控制的任何东西都不能改变这一点,因此您可能应该查看查询。

我的想法

我对你为什么要nvarchar(max)查询感到有点困惑 - 我希望nvarchar(4000)这就是我在测试系统上得到的结果。这个问题问的是: 为什么 code first/EF 在原始 SQL 命令中使用“nvarchar(4000)”作为字符串?(非常有趣的读物,那一个)。也许与 ADO .Net 版本有关,我不确定。

不管怎样,我已经说过,我将建议你无法影响这个值(至少,我相信你可以说服它,而nvarchar(4000)不是nvarchar(max)当然,但不能是其他任何东西)。

认为实体框架在生成这些查询时使用了 ADO .NET 中的自动参数化功能(请参阅:数据访问代码如何影响数据库性能)。本质上,我是说我怀疑他们只是将字符串值添加到 ADO .NET 中DbParameter并使用它来完成。

这真是一个耻辱,因为正如您所指定的那样,MaxLength它确实知道该字段有多长,但我也可以想象将 Lambda 表达式中的参数与其相关的列相加会有多复杂,所以我不完全惊讶。

所以,你可以做什么?

鉴于您无法更改这一点,尽管它确实会影响性能,正如您所建议的,我建议您集中精力减少运行的此类查询的数量。通常,最好的性能改进是通过调整查询的结构和计数来实现的,而不是像这样的小事情(只是我的经验,不要把它当作福音)。

例如,如果您正在执行类似SingleOrDefault(i => i.id ==x)循环内的操作,您可能希望将其转换为Where(i => xs.Contains(i.id))循环外的单个循环。那种事。我无法详细说明,但我确信您将能够使用其他方法来获得足够的性能。

祝你好运!