包含来自SQL Azure的具有大NVARCHAR值的列的查询很慢

lon*_*und 5 sql-server entity-framework azure-sql-database

我在Azure数据库中有一个表,它已经开始慢慢地对查询做出响应.查询看起来像:

SELECT [Id] --nvarchar(128), PrimaryKey
      ,[Name] --nvarchar(max)
      ,[Description] --nvarchar(max)
      ,[Modified]  --datetime2(7)
      ,[LastModifiedBy] --nvarchar(max)
      ,[Opened]  --datetime2(7)
      ,[Editor] --nvarchar(max)
      ,[Json] --nvarchar(max)   <--THIS IS GIVING ME PROBLEMS
      ,[IsActive] --bit
  FROM [dbo].[TableName]
Run Code Online (Sandbox Code Playgroud)

具体来说,当我在查询中包含[Json]列时,SQL查询性能从不到一秒钟变为几分钟.当包含[Json]列时,即使仅请求单个记录也可能需要几分钟.此列包含长json格式的字符串(~500000个字符).当包含此列时,性能仅会中断 - 包含较小字符串的其他NVARCHAR(max)列不是问题.

我通过使用Entity Framework linq-to-entities查询的MVC5应用程序的性能问题发现了这个问题:

var model=await db.TableName.FirstOrDefaultAsync(s => s.Id == id);
Run Code Online (Sandbox Code Playgroud)

它产生了一个类似上面的SQL查询.在本地开发机器上运行没有问题的单个案例的Edit方法在服务器上加载需要几分钟.然后我研究了直接的数据库查询,看看问题是什么,并找到了长查询时间.

在不同的查询方法中,此性能问题并不一致.

通过以下查询,我的周转时间为3分钟:

SELECT Json FROM [dbo].[TableName] WHERE [Id]=<id>
Run Code Online (Sandbox Code Playgroud)

周转时间与返回的字符串长度成指数比例.例如,此查询大约需要10秒钟:

SELECT SUBSTRING(Json,1,50000) FROM [dbo].[TableName] WHERE [Id]=<id>
Run Code Online (Sandbox Code Playgroud)

服务器上的查询如下所示:不到一秒钟:

DECLARE @variable nvarchar(max);
SELECT @variable=Json FROM [dbo].[TableName] where Id='<id>';
SELECT LENGTH(@variable);
Run Code Online (Sandbox Code Playgroud)

但实际上如下所示检索数据会让我回到几分钟:

DECLARE @variable nvarchar(max);
SELECT @variable=Json FROM [dbo].[TableName] where Id='<id>';
SELECT @variable;
Run Code Online (Sandbox Code Playgroud)

我的最终目标是弄清楚如何让Entity Framework的linq-to-entities查询以合理的速度执行,这样我就可以在C#中使用数据了,我认为我不能强制EF动态生成这样的查询.

在使用存储大字符串的其他表之前,我从未遇到过这种困难.是否有错误地设置错误的设置,或者在这种情况下是否有建立EF linq-to-sql语句的最佳实践?

为了进行比较,在具有相同数据库副本的SQL Server本地实例上运行查询时,没有性能问题; 所有查询都在不到一秒的时间内返回.

-UPDATE-

我一直在监控,这个问题已经消失,没有任何代码更改.所有查询响应时间都回到不到一秒.但是,Azure也没有关于服务中断的通知.事实上,在整个问题期间,数据库是完全可访问的,唯一的问题是涉及返回大字符串值的字段的慢查询.

缺点是我无法再重现这个问题.

对于在Azure上出现此问题的其他人(看起来不规则),此行为的诊断症状是:

  1. 没有Azure-SQL Server中断
  2. 不返回大字符串值的查询的健康响应时间
  3. Azure-SQL Server对任何查询的正常资源使用情况,即使它们返回大字符串值也是如此
  4. 在从属应用程序中,连接应用程序抛出两种类型的错误:a)连接超时错误,以及b)关闭的连接错误.没有任何上下文信息可以区分何时抛出任何类型的错误.
  5. 涉及长字符串的查询的响应时间是指向返回的字符串的长度.例如,10个字符是瞬时的,50000需要10秒,500000需要几分钟等.但是,响应时间不一致.
  6. 完全在服务器上执行的字符串处理(即使在非常长的字符串上)也不需要返回长字符串值需要正常的时间.

我会保留这个问题,以防有人得到实际答案,但似乎解决方案就是等待Azure解决他们正在修改的有关其请求处理的任何内容.似乎该问题与从Azure DB传输数据而不是服务器上的处理有关.我的最高建议是,如果问题的特征在于上面提到的症状,请不要拆开在开发盒上完美运行的代码.

Jov*_*SFT 1

这听起来像是返回 nvarchar(max) 的常见问题,因此也许最好联系 Azure 支持团队:

由于无法重现此问题,并且代码中没有任何修复,因此我不知道除了 Azure 支持团队之外的其他人可以提供帮助。