Почему LINQ to SQL работает лучше, чем прямой SQL-запрос? - PullRequest
2 голосов
/ 21 октября 2008

Странный результат производительности, у меня есть запрос LINQ to SQL, который использует несколько операторов let для получения различной информации, которая выглядит следующим образом

    public IQueryable<SystemNews> GetSystemNews()
{
    using (var t = new TransactionScope(TransactionScopeOption.Required,
              new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
    {
        var results = from s in _datacontext.SystemNews
                      let member = GetMemberInfo(s.MemberID)
                      let determination = GetDetermination(s.DeterminationID.Value)
                      let daimoku = GetDaimoku(s.DaimokuID.Value)
                      let entry = GetEntry(s.EntryID.Value)
                      let encouragment = GetEncouragement(s.EncouragementID.Value)
                      select new SystemNews
                      {
                          NewsDate = s.NewsDate,
                          MemberID = s.MemberID,
                          PhotoID = s.PhotoID.Value,
                          DeterminationID = s.DeterminationID.Value,
                          DaimokuID = s.DaimokuID.Value,
                          EntryID = s.EntryID.Value,
                          EncouragementID = s.EncouragementID.Value,
                          Member = new LazyList<Members>(member),
                          Determination = new LazyList<Determinations>(determination),
                          Daimoku = new LazyList<MemberDaimoku>(daimoku),
                          Entry = new LazyList<MemberEntries>(entry),
                          Encouragement = new LazyList<MemberEncouragements>(encouragment),
                          IsDeterminationComplete = s.IsDeterminationComplete.Value
                      };
        return results;
    }
}

Я создал ту же самую вещь (в основном, по крайней мере, различную информацию, полученную в этом) в представлении SQL, и LINQ to SQL вернул результаты менее чем за 90 миллисекунд, тогда как представление вернуло те же данные, фактически меньше информации за 700 миллисекунд. Кто-нибудь может объяснить это?

Ответы [ 4 ]

4 голосов
/ 21 октября 2008

В целом, LINQ-to-SQL будет "примерно таким же", и я согласен, что кеширование является проблемой здесь. На самом деле вам нужно посмотреть на сгенерированный SQL; самый простой способ:

_datacontext.Log = Console.Out;

Затем попробуйте запустить TSQL непосредственно в Query Analyzer. SPROC имеют некоторые преимущества с точки зрения возможности оптимизации доступа, использования табличных переменных и т. Д .; однако LINQ обладает преимуществом компоновки - то есть вы можете применить свои подкачки, сортировку, проекции и т. д. в одном запросе. Вы можете одним нажатием сделать это с помощью SPROC, но это очень тяжелая работа.

Но на самом деле ключ в том, чтобы взглянуть на TSQL; возможно, вы загрузили не все данные, например (отложенная загрузка).

1 голос
/ 21 октября 2008

Использовали ли вы профилировщик SQL для проверки различий между SQL, генерируемым LINQ, и SQL, который вы используете для сравнения?

Возможно, запрос LINQ to SQL лучше оптимизирован?

0 голосов
/ 23 июля 2009

На первый взгляд кажется, что ваш запрос Linq to SQL использует отложенную загрузку. Если я прав в этом, то имеет смысл, что выполнение вашего запроса фактически не запустит все части запроса в это время. Это означает, что если вы сравните его с представлением SQL, которое настроено на возврат всех этих результатов одним махом, то это определенно потребует больше усилий и, таким образом, потребует дополнительного времени.

Два других пункта:

  1. Убедитесь, что вы синхронизируете фактическое выполнение запроса, а не назначение выражения запроса. Помните, что запросы Linq откладываются, поэтому, когда вы возвращаете запрос из метода, описанного выше, он фактически возвращает выражение, а не результаты. В целом, три популярных способа заставить запрос Linq выполняться - это запустить методы расширения ToArray или ToList или просто перебрать результаты, используя foreach.

  2. Если вы на самом деле выполняете ленивую загрузку и синхронизируете фактическое выполнение запроса и по-прежнему получаете лучшие результаты в Linq to SQL, это может быть связано с различиями в том, что широкие сглаженные результаты возвращаются вашим SQL View в сравнение с узкими частями, запрашиваемыми несколько раз с помощью Linq to SQL.

Я никогда не делал никаких тестов по этому вопросу, чтобы увидеть, где находится переломный момент, но вы можете представить себе случай, когда у вас есть две таблицы Table1 и Table2, каждая из которых содержит 100 столбцов на таблицу и 1000 строк данных в Table1, которая также имеет отношение один ко многим к Таблице 2 и обычно дает 10 совпадений в Таблице 2 для каждой записи в Таблице 1. Теперь, если вы напишите представление для извлечения всех этих результатов обратно в одном запросе, вы ожидаете около 10000 строк данных и шириной около 200 столбцов. Однако, выполнив два отдельных запроса либо через Linq to SQL, либо с помощью любого другого механизма, вы можете вместо этого получить исходные 1000 строк по 100 столбцов с результатами из таблицы 1, а затем выбрать оставшиеся элементы таблицы 2, потенциально 10 000 строк, еще на 100 столбцов, что в общей сложности составит 1 100 000 ячеек ( что намного меньше, чем 2 000 000 ячеек из представления SQL). Преимущества становятся еще более преувеличенными, если предположить, что между зависимыми строками отношения «многие ко многим» существует значительное совпадение. В самом крайнем случае это перекрытие на 100%, что означает, что мы можем ожидать только 100 010 ячеек данных, которые будут извлечены, что намного меньше, чем 2 000 000, возвращенных при сглаженном виде.

0 голосов
/ 21 октября 2008

Вы, вероятно, видите эффект кэширования; это не реально.

Один из принципов бенчмаркинга заключается в том, что вы можете исказить свой бенчмарк в любом случае, запустив бенчмарк один раз, получив результаты в кеше, затем снова запустив его и сообщив о поразительных результатах, или, наоборот, ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...