Запросы LINQ vs Хранимые процедуры

Каковы преимущества и недостатки использования запросов linq (вместе с ORM, например EF или linq2sql) VS. Хранимые процедуры (SQL Server 2008) для запроса и обновления модели данных? Представление? Скорость? Etc...

Ответ 1

Linq определенно более читабельна, когда вы находитесь в коде. Видя вызов вызова sproc под названием "sp_GetSomething", вы ничего не говорите как разработчик, если вы не пойдете и не посмотрите физически на то, что делает sproc. вид кода

var query = from c in db.TableName
            where c.Name == "foo"
            select c;

Это точно указывает, какие данные извлекаются.

Сохраненные процедуры, с другой стороны, не требуют перекомпиляции приложения, если вы решите изменить код. Если вы решите внезапно изменить предложение "where" или изменить Order By - смена sproc проста. Изменение кода Linq может быть более трудоемким.

Я уверен, что есть еще много, но это два, которые я заметил.

Ответ 2

Существует 2 лагеря: для хранимых процедур и против хранимых процедур.

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

Практически

  • Если вы корпоративный программист, то вы никогда не измените свою платформу RDBMS. Вы реорганизуете своего клиента каждый раз, и вы будете переопределять свой DAL/репозиторий. Зачем? Используйте хранимые процедуры.
  • Если вы работаете с поставщиком, то вам, вероятно, придется поддерживать несколько РСУБД. ORM абстрагирует это в основном.

Я в корпоративном магазине, поэтому...

  • Плюсы: с Linq вам не нужно знать SQL
  • Минусы: вы ввернуты, когда что-то пойдет не так.

Мы (как разработчик команды DBA) часто вынуждены спасать пользователей ORM в сестринских командах.

Есть также более тонкие проблемы, такие как:

  • хранимые процедуры могут использоваться любым клиентом
  • перенесет ваш рефактор в EF или что-нибудь .net 5 приносит
  • инкапсуляция, предлагаемая хранимыми процедурами для абстрагирования схемы
  • уменьшены круглые поездки, потому что не должны храниться procs обрабатываться как методы или атомарные вызовы?

Ответ 3

@gbn имеет отличный ответ.

В огромных системах с сотнями миллионов записей, обработка данных на уровне представления просто не собирается сокращать его. Приложения с интенсивным использованием данных (а не приложения для ведения блога!) Должны будут масштабироваться раньше, чем вы думаете.

ORM - это огромная экономия времени при разработке системы от малого до среднего. Вы можете иметь готовое приложение для производства в кратчайшие сроки с правильно реализованным orm. никто не любит писать.

Также важно помнить, что синтаксис SQL был совместим более 20 лет. Если это не важно для вас, вы недостаточно долго программируете.

Ответ 4

Я бы почти всегда использовал хранимые процедуры по нескольким причинам:

1) Использование LINQ в коде для запроса базы данных на самом деле не соответствует принципам многоуровневой архитектуры... все, что связано с доступом к объектам базы данных, должно выполняться на уровне базы данных. Запросы LINQ - это всего лишь оболочка для написания SQL в вашем коде. SQL или LINQ в коде - нет-нет, хотя все примеры MVC это делают.

2) Производительность... хранимые процедуры DO выполняются быстрее! В любое время, когда вы выполняете запросы из кода, вы склонны к проблемам с масштабируемостью и производительностью.

3) Техническое обслуживание. Поскольку хранимые процедуры освобождают вас от наличия SQL или LINQ в вашем коде, обслуживание ваших хранимых процедур может быть принято отдельно (разделение проблем).

Ответ 5

Реальный ответ - это "лошади для курсов". С одной точки зрения (как db dev like @gbn), он хранит procs полностью. С моей точки зрения, как полнофункциональный веб-разработчик бэк-офиса, у которого одновременное использование приложений никогда не превышает 100, а кто не блестящий при написании эффективного SQL, это LINQ (в настоящее время EF 4.1) полностью. И код - во-первых, если мне это удастся. Это 15-й фрагмент, который я прочитал сегодня по этому поводу (после спора на встрече с разработчиком), и каждый фрагмент, похоже, предлагает то же самое - "лошади для курсов". И иногда, в мире бэк-офиса, это не просто эффективность сбора данных, которую вы должны учитывать, - насколько быстро (эффективно) вы можете исправить ошибки, и как легко (эффективно) следующий человек может видеть, что ваш код делает. С этой точки зрения LINQ выигрывает руки вниз.

Ответ 6

Это зависит от используемой вами версии SQL. План выполнения (который является информацией, используемой SQL для ускорения второго вызова...) в SQL 2008 отлично работает с O/RM. Я не понимаю, почему вы должны использовать O/RM и waiste много времени, переназначив все в пользовательский хранимый proc. Также хранится proc. вряд ли будет TDD и не позволит вам концепцию Unit of WOrk и транзакции

Ответ 7

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

В дополнение к комментариям Питера, еще несколько:

  • EF или Linq-to-SQL (или NHibernate тоже) являются ORM, что означает, что они хотят превратить строку в таблицу базы данных в объект. Поскольку этот объект обычно должен содержать все значения из этой таблицы (или даже из нескольких таблиц, в случае EF), эти ORM обычно используют подход SELECT * FROM ..... Это означает: поскольку вы выбираете все столбцы, вы, как правило, не можете использовать какие-либо индексы покрытия, и ваша производительность будет больно. Это классический компромисс "удобство против производительности"

  • Все ORM, о которых я знаю и с которыми работали, в основном нуждаются в полном доступе таблицы к базовым таблицам. Это большой нет-нет для многих предприятий и их DBA. Используя разумные методы хранения, вы можете обойтись без необходимости разрешать доступ к базе данных всех пользователей - большой плюс с точки зрения безопасности доступа!

Ответ 9

Ложная дихотомия. IMO, вы можете получить сладкое место как с помощью необработанного SQL (который является важным навыком, от которого мы не должны уклоняться) с инструментами, которые просто делают это удобным. Хранимые процедуры вводят некоторые проблемы связи/развертывания (время и т.д.), Что большинство людей не нуждается; ORM могут плохо работать. Большинство людей не собираются менять СУБД (и если они это сделают, это будет крупный проект в любом случае), поэтому: я большой поклонник параметризованного командного текста. И инструменты, которые помогают, например, dapper.

Другой пользователь разместил пример LINQ для фильтрации по имени; ну, вот то же самое в dapper:

string name = ...
var list = connection.Query<YourType>(
    "select * from TableName where [email protected]",
    new { name }).ToList();

Полностью параметризован; оптимизировано; безопасно; быстро; очистить; легко получить право. Выполнение задания.

Ответ 10

Мое предпочтение - LINQ, проверяя запросы, созданные в инструменте, таком как EF Profiler. Если какие-либо сгенерированные запросы слишком велики или создают N + 1, они обычно могут быть исправлены. Когда я нахожусь в производстве, я слежу за статистикой, и если медленный запрос не может быть исправлен путем кэширования, я переведу его в хранимую процедуру.

Основными преимуществами выполнения ваших запросов в linq являются:

  • Простое управление исходным кодом и изменение запросов развертывания.
  • Запросы скомпилированы, поэтому, если вы измените/переименуете что-то, что знаете, если что-то сломалось
  • Может unit test ваши запросы (возможно, есть способы сделать это с сохраненными процессами, но я не видел, чтобы кто-то это делал)
  • Можно легко отслеживать, где используются запросы, и удалять их больше не требуется.

Когда я присоединился к любому проекту, у которого много хранимых процессов, часто их много, которые не используются (или, вероятно, не используются), но никто не смеет их удалять, поскольку никто не уверен.

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

Ответ 11

Еще одна вещь, которую нужно добавить: Используя TSQL, вы можете создать пакет запросов, которые будут выполняться как unit, чтобы убедиться, что доступ к строкам заблокирован, пока вы не закончите свой список запросов. Пока я знаю, я думаю, что это невозможно сделать, используя LINQ.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Это очень полезно - например, если вы не хотите, чтобы новая вставка выполнялась во время выполнения списка запросов.

Ответ 12

Многое было сказано уже в ответ на исходный вопрос. Мой ответ основан на коммерческих аспектах, а не на технических. Вот мой опыт, возможно, это даст некоторые ориентиры тем, кто начинает новые проекты. Мы начали с Asp.net + SQL Server, и приложение перешло в сложное, используя около 800 хранимых процедур. В течение трех лет мы отправляем бесплатный SQL-сервер через программу Microsoft, поэтому никогда не заботились о ней раньше. Когда лицензионная котировка более 50 тыс. Попадает в таблицу (основанная на количестве ядер/потоков, и вам также нужна отдельная лицензия для подчиненного сервера), мы перешли на миграцию в MySQL. Пожелаем, чтобы мы не использовали хранимые процедуры. Без хранимых процедур мы могли бы легко быстро мигрировать в течение нескольких дней. Потребовалось гораздо больше времени и больших усилий, чтобы переписать SP в MySQL. Если вы не используете SP, ваше приложение более гибко/переносимо, и вам легче отлаживать код внутри вашего приложения.

Итак, если не технический, с коммерческой точки зрения, существует сильный аргумент против использования хранимых процедур в веб-приложениях. Если вы не используете SP, вы также можете распространять свое приложение для клиентов с помощью схемы db (которая будет включать только таблицы), в то время как ваша логика приложения по-прежнему скрыта в Linq + EF или Linq SQL.