Комментарии 21
НЛО прилетело и опубликовало эту надпись здесь
Лень тут не причем. Все зависит от того, что за проект у вас.
Естественно, если у вас высоконагруженный проект с большой БД и сложной логикой запросов к БД, то Entity Framework вам не подойдет, но дело в том, что огромное количество разработчиков разрабатывает стандартные проекты с маленькими БД (до 1 млн. строк). И вот для этих проектов EF приносит кайф. Попробуйте Lynq и вы увидите какое удовольствие писать запросы в стиле lambda expression. Также никто не мешает там где это надо вызвать хранимую процедуру или обратится к СУБД на чистом SQL.
Естественно, если у вас высоконагруженный проект с большой БД и сложной логикой запросов к БД, то Entity Framework вам не подойдет, но дело в том, что огромное количество разработчиков разрабатывает стандартные проекты с маленькими БД (до 1 млн. строк). И вот для этих проектов EF приносит кайф. Попробуйте Lynq и вы увидите какое удовольствие писать запросы в стиле lambda expression. Также никто не мешает там где это надо вызвать хранимую процедуру или обратится к СУБД на чистом SQL.
+13
Чем помогут хранимые процедуры? На практике отказ от хранимых процедур и переход к генерации запросов, например с помощью ef, в разы увеличивает быстродействие и скорость написания.
+6
Не могли бы вы поделиться пруфлинком по вопросу быстродействия?
0
Не могу, потому что результаты замеров на системах заказчика под NDA.
Но если знать немного SQL, то становится понятно, что linq-orm_ы могут построить проекцию (select) которая выбирает ровно то, что нужно для отображения. Тогда как в процедурах проекции будут широкие, ибо никто не хочет поддерживать десяток процедур.
Только эта особенность давала 20%-30% прирост в среднем на всех выборках.
А дальше для узких запросов можно удачно построить покрывающие индексы и ускорить запросы в разы.
Но если знать немного SQL, то становится понятно, что linq-orm_ы могут построить проекцию (select) которая выбирает ровно то, что нужно для отображения. Тогда как в процедурах проекции будут широкие, ибо никто не хочет поддерживать десяток процедур.
Только эта особенность давала 20%-30% прирост в среднем на всех выборках.
А дальше для узких запросов можно удачно построить покрывающие индексы и ускорить запросы в разы.
+1
>> Но если знать немного SQL, то становится понятно, что linq-orm_ы могут построить проекцию (select) которая выбирает ровно то, что нужно для отображения
Все это прекрасно можно сделать и на SQL.
>> Тогда как в процедурах проекции будут широкие, ибо никто не хочет поддерживать десяток процедур.
Видимо, вам просто не повезло с разработчиком БД. Понятно, что если писать плохой код, то и работать он будет плохо. Кстати, код на EF тоже надо поддерживать.
>> А дальше для узких запросов можно удачно построить покрывающие индексы
А SQL эти индексы использовать не будет?
Все это прекрасно можно сделать и на SQL.
>> Тогда как в процедурах проекции будут широкие, ибо никто не хочет поддерживать десяток процедур.
Видимо, вам просто не повезло с разработчиком БД. Понятно, что если писать плохой код, то и работать он будет плохо. Кстати, код на EF тоже надо поддерживать.
>> А дальше для узких запросов можно удачно построить покрывающие индексы
А SQL эти индексы использовать не будет?
-1
Все это прекрасно можно сделать и на SQL.
Как например? Дублируя SQL в каждой процедуре? Или клеить строки на стороне базы?
Я вот специально посидел в трасировщике и посмотрел какие запросы генерятся. Получилось около 15 разных запросов для одной таблицы. Причем большая часть запросов незначительно отличаются предикатом и проекцией. На практике я ни разу не видел 15 процедур с минимальными отличиями для одной таблицы. Админ задолбается такое поддерживать.
Видимо, вам просто не повезло с разработчиком БД. Понятно, что если писать плохой код, то и работать он будет плохо. Кстати, код на EF тоже надо поддерживать.Тут дело не в разработчике. Linq имеет средства декомпозиции запросов, поэтому на нем можно с помощью трех простых (точнее сказать примитивных) комбинаторов получить минимум 2^3=8 запросов.
На уровне СУБД того же самого можно добиться только склейкой строк или размножением количества процедур. И то и другое руками делать невозможно.
А SQL эти индексы использовать не будет?Даже если будет, то менее эффективно. Потому что покрывающий индекс работает идеально когда есть проекция с теми же полями, что в индексе. Но для случая процедур никто не будет создавать десятки процедур с разными проекциями и одинаковыми предикатами, чтобы индексы работали.
А еще часто бывает, что универсальные процедуры с кучей параметров и обычные индексы не цепляют из за множества предикатов вида @p is null or fld = @p.
+2
>> в разы увеличивает быстродействие
С этим я не могу согласиться.
T-SQL это могучая и крайне гибкая технология. Естественно, что для сложных запросов грамотно написанные хранимые процедуры будут намного более производительные, чем автоматически сгенерированный SQL код EF-ом, так как они могут в полной мере раскрыть все особенности и весь богатейший функционал СУБД MS SQL.
Мы используем EF во всех своих новых проектах, но когда сталкиваемся с действительной необходимостью оптимизации производительности, то мы используем хранимые процедуры, но на проект таких узких мест у нас на пальцах можно пересчитать.
А вот выгода в плане скорости разработки, уменьшения количества ошибок и отсутствие смены контекста между C#, Lynq и SQL, T-SQL при использовании EF приносят очень много позитивного в процесс разработки.
С этим я не могу согласиться.
T-SQL это могучая и крайне гибкая технология. Естественно, что для сложных запросов грамотно написанные хранимые процедуры будут намного более производительные, чем автоматически сгенерированный SQL код EF-ом, так как они могут в полной мере раскрыть все особенности и весь богатейший функционал СУБД MS SQL.
Мы используем EF во всех своих новых проектах, но когда сталкиваемся с действительной необходимостью оптимизации производительности, то мы используем хранимые процедуры, но на проект таких узких мест у нас на пальцах можно пересчитать.
А вот выгода в плане скорости разработки, уменьшения количества ошибок и отсутствие смены контекста между C#, Lynq и SQL, T-SQL при использовании EF приносят очень много позитивного в процесс разработки.
0
Естественно, что для сложных запросов грамотно написанные хранимые процедуры будут намного более производительные, чем автоматически сгенерированный SQL код EF-ом
За счет чего?
так как они могут в полной мере раскрыть все особенности и весь богатейший функционал СУБД MS SQL.
Например?
Мы используем EF во всех своих новых проектах, но когда сталкиваемся с действительной необходимостью оптимизации производительности, то мы используем хранимые процедуры, но на проект таких узких мест у нас на пальцах можно пересчитать.Мы все еще о запросах или о массовой обработке? При необходимости сразу обновить много данных процедуры рулят. Для запросов — тормозят. EF как раз для запросов и используется.
0
>> За счет чего?
За счет того, что универсальное решение практически всегда проиграет по производительности специализированному. Обратите внимание на то, как автор решает «проблемы» EF? Правильно, он по сути редактирует SQL-запрос, и пытается привести его к адекватному виду.
>> Например?
Например, рекурсивные запросы.
>> Мы все еще о запросах или о массовой обработке?
Вы под запросом понимаете выборку (SELECT) данных? Если да, то о них в частности. На самом деле в наших проектах самые сложные запросы связаны именно с выборкой данных.
За счет того, что универсальное решение практически всегда проиграет по производительности специализированному. Обратите внимание на то, как автор решает «проблемы» EF? Правильно, он по сути редактирует SQL-запрос, и пытается привести его к адекватному виду.
>> Например?
Например, рекурсивные запросы.
>> Мы все еще о запросах или о массовой обработке?
Вы под запросом понимаете выборку (SELECT) данных? Если да, то о них в частности. На самом деле в наших проектах самые сложные запросы связаны именно с выборкой данных.
+1
За счет того, что универсальное решение практически всегда проиграет по производительности специализированному.Именно. На практике как раз процедуры делают универсальными, покрывающими много сценариев, а linq генерирует специализированные запросы с проекциями, предикатами, постраничным разбиением, которые дают гораздо больше информации оптимизатору.
Например, рекурсивные запросы.
Рекурсивные запросы помогают быстродействию? Скорее наоборот. Лучше использовать hierarchyid и вычисляемые колонки или DDC. Для деревьев крайне не рекомендовал бы использовать CTE. А для графов быстрее получается весь граф втянуть в память приложения и работать с ним, чем писать CTE.
Может быть в других базах не так, но в SQL Server я более одного раза повышал быстродействие путем отказа от CTE.
+1
>> На практике как раз процедуры делают универсальными
Мне кажется, что вам просто не повезло с разработчиком БД. Поверьте и на EF можно писать очень плохо. Вы думаете мало тех, кто не использует проекции вообще и высасывает все данные методом ToList()? Это скорее говорит о низкой квалификации и безалаберном отношении к своей работе, чем об используемых технологиях.
>> Рекурсивные запросы помогают быстродействию?
Вы попросили пример использования особенностей MS SQL. Вот он.
Мне кажется, что вам просто не повезло с разработчиком БД. Поверьте и на EF можно писать очень плохо. Вы думаете мало тех, кто не использует проекции вообще и высасывает все данные методом ToList()? Это скорее говорит о низкой квалификации и безалаберном отношении к своей работе, чем об используемых технологиях.
>> Рекурсивные запросы помогают быстродействию?
Вы попросили пример использования особенностей MS SQL. Вот он.
+1
Поверьте и на EF можно писать очень плохо. Вы думаете мало тех, кто не использует проекции вообще и высасывает все данные методом ToList()? Это скорее говорит о низкой квалификации и безалаберном отношении к своей работе, чем об используемых технологиях.Я не просто верю, я регуоярно зарабатываю на проектах, где правлю такие косяки.
Но вопрос изначально был в том, что процедуры помогут сделать запросы быстрее. А пришли к тому что квалифицированный специалист с ХП сделает быстрее, чем неквалифицированный с EF. Но с таким утверждением никто и не спорил.
Вы попросили пример использования особенностей MS SQL. Вот он.
Давайте я еще раз процитирую ваше сообщение:
T-SQL это могучая и крайне гибкая технология. Естественно, что для сложных запросов грамотно написанные хранимые процедуры будут намного более производительные, чем автоматически сгенерированный SQL код EF-ом, так как они могут в полной мере раскрыть все особенности и весь богатейший функционал СУБД MS SQL.
То есть по вашему запросы в процедурах быстрее, потому что они могут использовать CTE. На практике быстрее сделать несколько вычисляемых индексированных колонок и пользоваться EF или вообще перенести обработку на уровень приложения.
0
Мне кажется, что можно сформулировать и доказать следующее:
Для любого запроса, который сгенерирован генератором SQL кода, найдется такой запрос, написанный на SQL (возможно в паре с T-SQL), который не будет уступать в производительности сгенерированному.
Что думаете?
Для любого запроса, который сгенерирован генератором SQL кода, найдется такой запрос, написанный на SQL (возможно в паре с T-SQL), который не будет уступать в производительности сгенерированному.
Что думаете?
0
По-моему это очевидно. Проблема не в том как написать один запрос, а в том как сделать все (или те которые используются чаще всего) запросы в программе максимально быстрыми. Руками написать все такие запросы уже проблематично, а поддерживать — сущий ад. В большинстве случаев запросы будут отличаться небольшими деталями в предикатах и проекциях, а средств декомпозиции в SQL очень мало.
+1
все описанные проблемы также актуальны для EF7?
+1
релиз EF7 ожидается в первом квартале 2016 г. Здесь можно посмотреть на некоторые новые возможности EF7:
https://github.com/aspnet/EntityFramework/wiki/Roadmap
EF7 это скорее не продолжение EF6, а переписанная чуть ли не с нуля ORM.
https://github.com/aspnet/EntityFramework/wiki/Roadmap
EF7 это скорее не продолжение EF6, а переписанная чуть ли не с нуля ORM.
+3
Вы капитан очевидность. Именно потому что она переписана чуть ли не с нуля и возник вопрос актуальности проблем, описанных статье.
+1
В любом случае надо дождаться релиза EF 7 и проверить. Кстати, я бы не назвал описанные в статье случаи проблемами, хотя бы потому, что автор тут же в статье привел варианты их решения и почти все решения базируются на возможностях EF т. е. это скорее тонкости работы с EF, чем проблемы.
+2
Как уже написали выше — часть описанного в статье скорее не проблемы фреймворка, а нюансы, о которых нужно знать и учитывать при написании кода. Например, все, что связано с AsNoTracking и AutoDetectChangesEnabled — справедливо и для EF7 и так и останется. Очевидно, что трекинг и определение изменений нужны во многих сценариях, и что они вносят дополнительные вычислительные расходы. Просто нужно знать, когда их можно отключить.
Проблемы с перекомпиляцией запроса для Contains, Take и Skip тоже актуальны для EF7, причем в нем пока еще нет перегруженых Take и Skip, принимающих лямбда-выражение. Т.е. на данный момент в нем все запросы, содержащие Take и Skip будут перекомпилироваться при каждом выполнении.
Насчет остального — надо проверять, причем лучше всего уже на релизной версии.
Проблемы с перекомпиляцией запроса для Contains, Take и Skip тоже актуальны для EF7, причем в нем пока еще нет перегруженых Take и Skip, принимающих лямбда-выражение. Т.е. на данный момент в нем все запросы, содержащие Take и Skip будут перекомпилироваться при каждом выполнении.
Насчет остального — надо проверять, причем лучше всего уже на релизной версии.
+3
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Подводные камни Entity Framework и производительность