Каково влияние LinqToSql на производительность по сравнению с обычным ADO.Net для очень простой базы данных SQL Server? - PullRequest
1 голос
/ 27 мая 2011

Я занимаюсь разработкой приложения для обработки чисел на C #. Он будет использовать базу данных с очень простой структурой таблиц (хотя и с множеством записей) и не иметь одновременно работающих клиентов (но, возможно, с несколькими потоками) для доступа к ней, но будет выполнять многие многие тысячи последовательных операций получения / вставки / обновления. Мне лучше использовать простой запрос ADO.Net или LinqToSQL?

Для меня это не выглядит очевидным - может быть, LinqToSql лучше из-за буферизации (+ читаемость), а может, плохо из-за накладных расходов.

ОБНОВЛЕНИЕ 1:

У меня здесь очень простая модель - 3 таблицы по 10 полей в каждой. Нет внешних ключей (нормализация принесена в жертву принципу KISS). Я мог бы использовать для этого таблицы Excel, но я предпочитаю кодировать C # + SQL, а не VBA и считаю, что SQL Server работает быстрее (и допускает больше записей).

ОБНОВЛЕНИЕ 2:

Мне на самом деле не нужен ORM, достаточно простого SQL-запроса. Я рассматриваю LinqToSql по трем причинам: 1. он позволяет визуально генерировать базу данных сначала на диаграмме, 2. LINQ выглядит лучше, чем запросы в виде строковых литералов. 3. логически кажется, что может (или не может) увеличить производительность за счет массовых обновлений / вставок, кэшированных чтений и отложенной загрузки.

ОБНОВЛЕНИЕ 3:

У меня есть 4 ГБ оперативной памяти, и я не против, чтобы приложение использовало все концерты при обработке данных.

Ответы [ 5 ]

2 голосов
/ 27 мая 2011

Каждый раз, когда вы выполняете такой объем последовательного доступа к данным, возникает несколько очевидных вопросов (которые не имеют ничего общего с LINQ-to-SQL по сравнению с необработанным ADO.NET):

  • не могли бы вы получить списки, а не получить
  • Не могли бы вы сделать все это в базе данных

LINQ-to-SQL добавляет много удобства и статической проверки, а обычно накладные расходы довольно минимальны; однако, если вы загрузите много (тысячи) записей в один контекст данных, у менеджера идентификации будет больше работы, что может незначительно повлиять на производительность. Мы также иногда замечаем необъяснимые паузы во время загрузки LINQ-to-SQL (т. Е. TSQL займет 1 мс, а объекту потребуется 80 мс для материализации) - это было спорадическим и трудным для воспроизведения, но для массовой работы мы в итоге написали dapper в качестве замены-замены, позволяющей удобную материализацию в стиле LINQ-to-SQL, без этих накладных расходов - но также без возможности изменять его и сдвигать изменения вниз; p Конечно, вы можете попробовать Attach и т. д.

2 голосов
/ 27 мая 2011

Сэм Саффрон создал микро ORM под названием dapper. На веб-сайте проекта есть некоторые тесты, на которые вам может быть интересно посмотреть.Они сравнивают необработанный DataReader с различными реализациями ORM, включая LinqToSql

1 голос
/ 27 мая 2011

В общем, учитывая ваше описание, вы будете в порядке с Linq-to-sql

Слово предупреждения - вы пишете в своем вопросе

логически кажется, что это может (или не может) повысить производительность за счет массового обновления / вставки коммитов, кэшированного чтения и отложенной загрузки.

Linq, безусловно, не увеличит вашу производительность в случае массовых обновлений / вставок. Напротив, массовые обновления с SP или массовые вставки с SqlBulkCopy на порядок быстрее, чем Linq-sql.

0 голосов
/ 29 мая 2011

, чтобы получить к нему доступ, но делать много-много тысяч последовательных операций получения / вставки / обновления.

Если это то, что вы делаете, вам следует использовать ADO.Net.

Существует пять способов запроса данных одной таблицы с помощью LinqToSql.Здесь они примерно медленнее, чем быстрее:

Последовательное получение

Это медленно, потому что дерево выражений должно быть переведено в sql, и для каждой строки должно выполняться обратное путешествие по базе данных .*

N деревьев выражений и генерация динамических методов.Обращения к базе данных N.

from c in myDC.Customers where c.Id = myId select c;

Последовательный CompiledQuery

1 дерево выражений и генерация динамического метода.Обращения к базе данных N.

Func<MyDataContext, int, IEnumerable<Customer>> compiledQuery =
  (dc, i) => from c in dc.Customers where c.Id = i select c;

Ranged получает

N / PageSize дерево выражений и генерацию динамического метода.N / PageSize обходы базы данных.

(from c in myDC.Customers where c.Id > myId order by c.Id select c).Take(pageSize)

Option2

  --note, sql server has an upper limit of ~2100 parameters.
from c in myDC.Customers where myIds.Contains(c.Id) select c;

Скомпилированный Ranged получает

1 дерево выражений и генерацию динамического метода.N / PageSize обходы базы данных.

Func<MyDataContext, int, IEnumerable<Customer>> compiledQuery =
  (dc, i) => from c in dc.Customers where c.Id > i order by c.Id select c).Take(pageSize)

Option2

--note, .Contains method not supported by compiled query due to varying parameter count.
--instead the expression has to be built from the ground up - this is hard, but not impossible.

Табличный дамп

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

from c in myDC.Customer select c;

В ADO.Net вы не выполняете преобразование Expression-> Sql и методэто превращает строки DataReader в объекты, написанные вами, а не генерируемые динамически.По умолчанию производительность должна быть на уровне CompiledQuery.

0 голосов
/ 27 мая 2011

Не заботьтесь о накладных расходах какой-либо технологии, если только вы не работаете над проектом, чувствительным к высокой производительности, или у вас не возникают измеримые проблемы с производительностью.

Преждевременная оптимизация - корень всего зла. Посмотрите на http://c2.com/cgi/wiki?PrematureOptimization

В ответ на комментарии: мой первоначальный ответ был в основном нацелен на последнюю часть вопроса, в которой ОП выражает озабоченность по поводу накладных расходов технологии более высокого уровня (запросы LINQ) по сравнению с технологией более низкого уровня (необработанные запросы) , Конечно, вы не должны игнорировать производительность вообще. Но так как OP говорит о довольно простом типе приложений, это должно иметь большое значение с точки зрения производительности. В этих случаях я всегда выбирал бы технологию более высокого уровня из-за читабельности, гибкости и удобства обслуживания.

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