|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Сгенерировал я тут себе DataContext с 250-ю DbSet-ами по XML-схеме при помощи TT и CodeDom. После первых тестов выяснилось, что время, затрачиваемое на построение модели составляет примерно 30 секунд, что, граждане - полный ппц для "рекомендуемой Microsoft технологии доступа к данным". Засел на неделю в библиотеку на предмет поиска путей оптимизации. Интернет нарекомендовал а) натравить ngen на сборки EntityFramework б) разбить DbContext-а на два по 125 сущностей (предметная область это позволяет) в) подключить EF Power Tools или EF Interactive Views для прегенерации г) отключение DbInitializer (синхронизировать базу и модель мне не нужно). В результате титанических усилий добился уменьшения времени построения модели до 12 секунд Теперь сижу и размышляю, что с этим недоразумением под названием EF делать. С одной стороны рукопашное сохранение графа записей через старый добрый SqlCommand инициализируется за миллисекунды и выполняется десятые доли секунды (в тестах на пике до 5000 инсертов/сек), хотя и требует неких усилий на кодогенерацию. С другой стороны чтение базы, безусловно, удобнее через EF/Linq. С третьей - 12 секунд. С четвертой стороны, бытует мнение, что EF это мулька в основном для веба, и что после первой инициализации модели она закешируется в AppDomain и последующие обращения к новому экземпляру DbContext будут происходить мгновенно. С пятой, клиенты у меня будут преимущественно дескопные. С благодарностью приму всякие советы и рекомендации по выходу из логического тупика. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:13 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Какая версия EF ? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:18 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
6.1.3 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:19 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbda6.1.3Та же версия. Наблюдаю 166 таблиц, DbContext API, описано через атрибуты DataAnnotations, миграции отключены. Всё "летает", на "старте" особых замедлений не замечено. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:50 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaпосле первой инициализации модели она закешируется в AppDomain и последующие обращения к новому экземпляру DbContext будут происходить мгновенно. так я не понял, у тебя что, не кэшируется или в чем проблема? первый раз долго, потом быстро, так и должно быть, хоть веб, хоть десктоп. можно еще другие orm использовать, всякие dapper например. что бы читать чуть быстрее в EF можно юзать .AsNoTracking() когда очень надо, что бы писать быстро я использую ADO.NET SqlBulkCopy ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:58 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
"Летает" - это сколько у вас в секундах/миллисекундах на первую инициализацию модели CodeFirst? И еще можно поинтересоваться, как в вашей модели с наследованием? У меня в модели около 10 базовых классов, все остальные это наследники (до 5 уровней). Таблицы сформированы по принципу Table-Per-Type, без дискриминатора. Может быть, это как-то влияет? Запросы на select EF-ом порождаются конкретно монструозными. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:59 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Var79, а) долго инициализируется при первом вызове б) после инициализации конкретно жрёт память (до гигабайта) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:00 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaС четвертой стороны, бытует мнение, что EF это мулька в основном для веба,Это пусть каждый сам для себя решает. pbdaи что после первой инициализации модели она закешируется в AppDomain и последующие обращения к новому экземпляру DbContext будут происходить мгновенно.Да, сначала всё что можно кэшируется, последующие обращения происходят мгновенно. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:01 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbda, да какая разница сколько на первую инициализацию? в 10 - 20 сек влезает и норм ведь не только контекст подтормаживает от первой инициализации ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:05 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbda"Летает" - это сколько у вас в секундах/миллисекундах на первую инициализацию модели CodeFirst?Ну где-то пара секунд, чисто визуально, точно не измерял. pbdaИ еще можно поинтересоваться, как в вашей модели с наследованием? У меня в модели около 10 базовых классов, все остальные это наследники (до 5 уровней). Таблицы сформированы по принципу Table-Per-Type, без дискриминатора. Может быть, это как-то влияет?Наследованием сущностей из контекста не пользуемся. Может и влияет, не проверял. pbdaЗапросы на select EF-ом порождаются конкретно монструозными.Главное, что планы выполнения мало отличаются от рукописных. Остальное не важно, ну мне так кажется. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:07 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaпосле инициализации конкретно жрёт память (до гигабайта) на всякий случай, в курсе что контекст IDisposable и его нужно брать в using() ? что именно жрет гигабайт, всё приложение или сколько экземпляров контекста? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:08 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Алексей К, Всё-таки похоже, что дело в наследовании. Погуглил EF TPT entity inheritance performance. https://www.codeproject.com/articles/66313/the-entity-framework-v1-and-v4-deal-breaker-tpt-in.aspx If you need this type of design, or think that your software at some point in the future will require this type of design, DO NOT use the Entity Framework. The Table-Per-Type inheritance is 100% unusable. Статья от 2010 года, правда ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:12 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaб) после инициализации конкретно жрёт память (до гигабайта)Это странно, не могут метаданные занимать столько места. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:12 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Var79, Знаю и про Disposable и про using. Память отъедается во время первого обращения к навигационным свойствам наследника DbContext либо при вызове SaveChanges (в этот момент и происходит построение модели в памяти). ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:14 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaСтатья от 2010 года, правдаНо с того времени EF стал намного лучше, просто "как небо и земля". Но всё может быть, я за наследование не подскажу, может ещё кто знает. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:15 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbda, если в память тащить из базы содержимое всех таблиц, то понятно, если прочитал и забыл, то может дело не в контексте, а в том что что то не собирается GC? WCF сервис с более 100 таблиц с наследованием занимает меньше 300 мб всего. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:18 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaб) после инициализации конкретно жрёт память (до гигабайта)Может тянутся данные из БД из-за ленивой загрузки? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:25 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Алексей К, на SaveChanges тоже память ест. В общем, всем спасибо, почитал еще и вот это и теперь почти на 100% уверен, что проблема у меня - в наследовании и TPT. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:35 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaАлексей К, на SaveChanges тоже память ест. В общем, всем спасибо, почитал еще и вот это и теперь почти на 100% уверен, что проблема у меня - в наследовании и TPT. А что если запустить профайлер и посмотреть? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 14:17 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
1. Для ускорения поднятия метаданных модели можно использовать Precompiled views. Мы из модели code-first в билд-процессе строим EDMX и вьюхи, все сохраняем в ресурсах сборки. Билд всего этого хозяйства (1300 классов в модели с кучей навигаций между ними) занимает секунд 40, зато в рантайме поднимается за 3 секунды. 2. Запросы к иерархиям TPT, действительно, не самые быстрые. Более того, EF не строит precompiled views для дочерних типов любых иерархий, и первый из запросов к иерархии в рантайме достраивает эти вьюхи в метаданных. Таким образом, если есть способ не делать иерархию - лучше ее не делать. Если есть возможность вместо TPT сделать TPH - лучше сделать так. В отдельных сценариях неплох и TPC. 3. В коде EF действительно есть тормозные места. Мы выявляли их профилированием и правили в исходниках EF. Так, генерацию плана запроса удалось ускорить почти в 2 раза. Также дорабатывали плюшки, например, для использования временных таблиц и динамического SQL в запросах LINQ. Наличие самопального кода, конечно, может потенциально затруднить переход на очередную версию EF, однако MS что-то на EF6 подзабила, а EF7 настолько сырой, что использование его в продакшене пока не представляется возможным. Те же иерархии TPT пока что не реализованы, более того - находятся в самом конце roadmap. Возможность смешивать TPT и TPH в одной иерархии (у нас есть и такое) вообще в EF7 объявлена как deprecated. PS Кстати, веселое обсуждение issue на гитхабе https://github.com/aspnet/EntityFramework/issues/2266 Здесь представители MS объявили TPT антипаттерном, а разъяренные юзеры таки-продавили включение TPT в roadmap. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 17:45 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
Gluck_131. Для ускорения поднятия метаданных модели можно использовать Precompiled views. Мы из модели code-first в билд-процессе строим EDMX и вьюхи, все сохраняем в ресурсах сборки. Precompiled views это я уже умею. А как из Code First сделать EDMX и какие в нем дополнительные плюшки? Gluck_132. Запросы к иерархиям TPT, действительно, не самые быстрые. Более того, EF не строит precompiled views для дочерних типов любых иерархий, и первый из запросов к иерархии в рантайме достраивает эти вьюхи в метаданных. Таким образом, если есть способ не делать иерархию - лучше ее не делать. Если есть возможность вместо TPT сделать TPH - лучше сделать так. В отдельных сценариях неплох и TPC. Если сделать TPH то получится 10 таблиц, в каждой по 200 полей... оставлю на самый крайний случай :) Сейчас попробую помапить сущности на представления базы данных, которые сводят иерархии в плоские представления. Если дело действительно в наследовании, то это должно сильно улучшить картину. Gluck_13однако MS что-то на EF6 подзабила, а EF7 настолько сырой, что использование его в продакшене пока не представляется возможным. Это да. Я от отчаяния даже EF Core успел пощупать. По готовности он примерно как EF7. Gluck_13PS Кстати, веселое обсуждение issue на гитхабе https://github.com/aspnet/EntityFramework/issues/2266 Здесь представители MS объявили TPT антипаттерном Спасибо, посмеялся ) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 19:23 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaЭто да. Я от отчаяния даже EF Core успел пощупать. По готовности он примерно как EF7. Эм, так EF Core и EF7 это же одно и тоже, не? у меня используется TPC ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2016, 06:44 |
|
EF6 CodeFirst performance как дальше жить
|
|||
---|---|---|---|
#18+
pbdaСгенерировал я тут себе DataContext с 250-ю DbSet-ами по XML-схеме при помощи TT и CodeDom. pbdaEF6 CodeFirst Вы реально будете использовать все 250 (125) DbSet-ов одновременно?) Разделите контексты на еще более мелкие и в каждом контексте сделайте свои проекции моделей, которые будут содержать только нужные вам данные. Если вам не нужен трекинг изменений, делайте AsNoTracking() или отключите трекинг изменений в конфигурации. Так же можно запретить создавать прокси типы ваших моделей. pbdaС одной стороны рукопашное сохранение графа записей через старый добрый SqlCommand инициализируется за миллисекунды и выполняется десятые доли секунды (в тестах на пике до 5000 инсертов/сек), хотя и требует неких усилий на кодогенерацию. С другой стороны чтение базы, безусловно, удобнее через EF/Linq. Возможно, в таком случае вам стоит взять тот же Dapper для чтения базы, а для записи использовать "старый добрый SqlCommand" (CQRS). ... |
|||
:
Нравится:
Не нравится:
|
|||
29.01.2017, 15:25 |
|
|
start [/forum/topic.php?fid=17&msg=39360318&tid=1349320]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
236ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 347ms |
0 / 0 |