wcf序列化linq结果会导致大量的sql server加载

时间:2010-07-09 11:46:10

标签: sql-server wcf performance linq-to-sql serialization

我正在尝试使用linq从数据库中获取WCF服务的序列化结果。

db中的表在某种程度上被规范化了,我将使用Data.Linq.DataLoadOptions返回一些其他数据以及我最初使用linq查询检索的on,就像在Scott Landford的Blog中一样:{{3 }}

以下是我的相关代码的一部分:

    ServerDALDataContext db = new ServerDALDataContext();

    System.Data.Linq.DataLoadOptions dlo = new System.Data.Linq.DataLoadOptions();
    // get COMPETITOR_ENTRies data along with COMPETITION
    dlo.LoadWith<COMPETITION>(e => e.COMPETITOR_ENTRies);
    // get dividends for competitors along with COMPETITOR_ENTRies
    dlo.LoadWith<COMPETITOR_ENTRY>(e => e.DIVIDENDs);
    db.LoadOptions = dlo;

    // retrieve MEETING data from database
    var competitions = (from c in db.COMPETITIONs
                        select c)
        .AsEnumerable()
        .Where(c => c.CONTROL_UPDATE_DATA.FOR_UPDATE); 
            && c.COMPETITION_DATETIME.Value.Date == dateFrom.Date);

    // return as list            
    return competitions != null ? competitions.ToList() : null;

还有一个客户端应用程序使用该服务,每隔10秒左右就向WCF服务发送异步请求。

引起的问题是,当使用它时,它实际上会使SQL服务器超载,以至于它一直使用100%的CPU,导致对客户端的响应延迟。我删除了dlo.LoadWith调用和响应是在一个有意义的时间。

有关如何解决此问题的任何建议,而不是过多地重载SQL服务器?

1 个答案:

答案 0 :(得分:1)

// retrieve MEETING data from database 
var competitions = (from c in db.COMPETITIONs 
                    select c) 
    .AsEnumerable() 
    .Where(c => c.CONTROL_UPDATE_DATA.FOR_UPDATE);  
        && c.COMPETITION_DATETIME.Value.Date == dateFrom.Date); 

... AsEnumerable

你正在加载整个表格。


  

在这种情况下,什么是好方法?

设置dataContext.Log = Console.Out;或启动sql profiler并查看发送到数据库的内容。

有两种可能性:

  1. 您正在向数据库发送过滤后的查询,这些查询可以获取您想要的结果 - 但它们表现不佳。将查询放入SqlStudio并单击“显示估计执行计划”按钮。还可以使用SET STATISTICS IO ONSET STATISTICS TIME ON,然后查看消息标签。解决方案通常涉及添加索引。

  2. 您正在发送经过严格筛选的查询或逐段获取数据的查询(许多往返)。返回生成查询的c#代码并找出错误。解决方案通常涉及正确放置Where,或者执行Join而不是GroupBy,并且在循环中绝对不执行查询。


  3. 使用时间修剪的正确日期过滤:

    DateTime theDate = DateTime.Now;
      //manipulate date into a range locally.
    DateTime startDate = theDate.Date;
    DateTime endDate = startDate.AddDays(1);
    
      //filter by the range - endpoint excluded.
    IEnumerable<Order> query = myDC.Orders.Where(order =>
       startDate <= order.OrderDate
       && order.OrderDate < endDate);