wcf serialize linq результаты вызывает огромную нагрузку на сервер sql - PullRequest
0 голосов
/ 09 июля 2010

Я пытаюсь получить сериализованные результаты из службы WCF из базы данных, используя linq.

Таблицы в БД в некоторой степени нормализованы, и я возвращаю некоторые другие данные вместе с тем, что я изначальнополучить с помощью запроса linq, используя Data.Linq.DataLoadOptions, как в блоге Скотта Лэндфорда: http://codeexperiment.com/post/Returning-LINQ-to-SQL-Entities-From-WCF.aspx

Вот часть моего кода, которая имеет отношение:

    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;

Есть такжеклиентское приложение, которое использует службу и отправляет асинхронные запросы службе WCF каждые 10 секунд или около того.

Проблема, которая возникает, заключается в том, что при использовании она фактически перегружает сервер SQL до такой степени, чтовсе время использует процессор на 100%, что приводит к задержке ответов клиента.Я удаляю вызовы dlo.LoadWith, и ответы приходят в значимое время.

Любые предложения о том, как решить эту проблему, и не слишком ли сильно перегружать сервер SQL?

1 Ответ

1 голос
/ 09 июля 2010
// 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 и посмотрите, что отправляется в базу данных.

Оттуда две возможности:

  1. Вы отправляете в базу данных хорошо отфильтрованные запросы, которые извлекают нужные вам результаты - но они работают плохо. Поместите запросы в SqlStudio и нажмите кнопку «Показать примерный план выполнения». Также используйте SET STATISTICS IO ON и SET STATISTICS TIME ON, затем посмотрите на вкладку сообщений. Решение обычно включает добавление индексов.

  2. Вы отправляете плохо отфильтрованные запросы или запросы, которые извлекают данные по частям (много циклических переходов). Вернитесь к коду C #, который сгенерировал запросы, и выясните, что это за ошибка. Решения обычно включают в себя правильное размещение Where или выполнение Join вместо GroupBy, и определенно не выполняется запрос в цикле.


Надлежащая фильтрация даты с временной отсечкой:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...