我在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]
具体来说,当我在查询中包含[Json]列时,SQL查询性能从不到一秒钟变为几分钟。当包含[Json]列时,即使仅请求单个记录也可能需要几分钟。此列包含长json格式的字符串(~500000个字符)。当包含此列时,性能仅会中断 - 包含较小字符串的其他NVARCHAR(max)列不是问题。
我通过使用实体框架linq-to-entities查询的MVC5应用程序的性能问题发现了这个问题:
var model=await db.TableName.FirstOrDefaultAsync(s => s.Id == id);
生成了一个类似上面的SQL查询。在本地开发机器上运行没有问题的单个案例的Edit方法在服务器上加载需要几分钟。然后,我查看了直接数据库查询以查看问题所在并找到了较长的查询时间。
这种性能问题在不同的查询方法中并不一致。
我的周转时间为3分钟,并带有以下查询:
SELECT Json FROM [dbo].[TableName] WHERE [Id]=<id>
周转时间与返回的字符串长度成指数比例。例如,此查询大约需要10秒钟:
SELECT SUBSTRING(Json,1,50000) FROM [dbo].[TableName] WHERE [Id]=<id>
服务器上的查询(如下所示)不到一秒钟。:
DECLARE @variable nvarchar(max);
SELECT @variable=Json FROM [dbo].[TableName] where Id='<id>';
SELECT LENGTH(@variable);
但实际上如下所示检索数据会让我回到几分钟:
DECLARE @variable nvarchar(max);
SELECT @variable=Json FROM [dbo].[TableName] where Id='<id>';
SELECT @variable;
我的最终目标是弄清楚如何让Entity Framework的linq-to-entities查询以合理的速度执行,这样我就可以使用C#中的数据了,我认为我不能强制EF生成这样的动态查询。
在使用存储大字符串的其他表之前,我从未遇到过这种困难。是否有错误地设置错误的设置,或者在这种情况下是否有建立EF linq-to-sql语句的最佳实践?
为了进行比较,使用同一数据库的副本在SQL Server的本地实例上运行查询时没有性能问题;所有查询都在不到一秒的时间内返回。
-UPDATE -
我一直在监控,这个问题已经消失,没有任何代码更改。所有查询响应时间都回到不到一秒。但是,Azure也没有关于服务中断的通知。事实上,在整个问题期间,数据库是完全可访问的,唯一的问题是涉及返回大字符串值的字段的慢查询。
缺点是我无法再重现这个问题。
对于Azure上存在此问题的其他人(似乎不规则),此行为的诊断症状为:
如果某人有实际答案,我会保留此问题,但似乎解决方案是等待Azure解决他们正在修改的有关其请求处理的任何内容。似乎该问题与从Azure DB传输数据而不是服务器上的处理有关。 我的最高建议是,如果问题的特征是上述症状,请不要拆开在开发盒上完美运行的代码。
答案 0 :(得分:1)
真的太糟糕了,你无法重现这个错误,因为我已经考虑过你的问题,而这一切都来自你的陈述&#34;当我在[Json]列中包含查询时,SQL查询性能从不到一秒钟到几分钟。&#34;你也给了我一些线索:
服务器上的查询(如下所示)不到一秒钟。:
DECLARE @variable nvarchar(max);
SELECT @variable=Json FROM [dbo].[TableName] where Id='<id>';
SELECT LENGTH(@variable);
检索数据时,问题是等待类型:ASYNC_NETWORK_IO。基本上将数据发送出sql server并进入应用程序等待就是问题所在。
我会问应用程序在哪里运行。应用程序是否位于与数据库相同的数据中心中,或者是否在数据中心外部运行。越接近应用程序数据,您就越少看到此等待类型。
我要问的另一个问题是运行应用程序的硬件,它是否有足够的内存来接收所有数据,然后以有用的方式处理它。有时,网络等待实际上是应用程序端的供电硬件问题。
我还有一些额外的想法要分享:如果您要处理非常大的JSON对象,您是否考虑过使用DocumentDB来存储它们,而不是Azure SQL数据库?它针对这种工作负载进行了优化,现在您可以编写T-SQL来查询存储在DocumentDB中的JSON文件。
关于:
在依赖应用程序中,连接应用程序抛出两种类型的错误:a)连接超时错误,以及b)关闭的连接错误。没有任何上下文信息可以区分何时抛出任何类型的错误。
在任何打到数据库的应用程序中,您都需要某种重试策略。在处理Azure SQL数据库时,这是至关重要的,因为在任何给定时间您都有三个数据库副本,并且您可能需要在一天中间进行故障转移。如果您有重试策略,最终用户将永远不会知道存在问题,因为辅助副本可在一秒钟内完成。
我希望这有帮助!
答案 1 :(得分:0)
这听起来像是返回nvarchar(max)的一般问题所以也许联系Azure支持团队会更好:
由于此问题可以重现并且代码中没有一些修复,因此我不知道Azure支持团队以外的其他人如何提供帮助。