Re[28]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 16.04.15 22:05
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>Во-первых, на C++ ручками 2**N запросов выписывать не нужно — это автоматически разруливается с помощью метапрограммирования. То есть задав N runtime условий, и N кусочков запросов (да и вообще любого кода), можно автоматом получить оптимизированный код для 2**N случаев.

EP>>>Возможно ли что-то подобное в рамках C#? (по N условиям получить автоматом 2**N Compiled Queries)
EP>>>И как это будет выглядеть в случае когда куски запроса в разных dll?
G>>Такой задачи никогда не ставилось.

EP>Пусть и не ставилась — мне интересно возможно ли это в рамках C# или нужны внешние инструменты.

Да в принципе можно, никто не мешает нагенерить Expression и прогнать все через compiled query. Только абсолютно непонятно зачем.

G>>Да и смысла немного в этом. Пара миллисекунд

EP>Пара миллисекунд практически на ровном месте. Да это же 1/50 секунды современного железа! В 3D приложениях за столько целый кадр отрисовывается, да — там по большей части GPU, но всё же — одно ядро CPU за это время может выполнить около миллиарда операций с плавающей точкой, а из RAM можно загрузить сотни мегабайт.
Увы, в реальности корпоративных приложений процессор большую часть времени отдыхает. Основные затраты на общение с внешними системами и перекачку данных по сети. Их никаким образом не получится соптимизировать путем уменьшения времени создания и обхода expression tree. Так что ты не в том месте оптимизировать пытаешься.


EP>Для десктопных GUI приложений это может и не существенно, но для остальных применений может очень сильно ударить, тем более если запрос не один в секунду. Не зря же появляются такие вещи как Massive, PetaPoco, Dapper — значит есть на них спрос.

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

G>>и то если попадания в кеш не было.

EP>Какой конкретно cache?
Любое серьезное приложение использует application cache, чтобы уменьшить время на передачу по сети и чтение с диска. А в случае есть еще кеши веб-сервера и клиента.

EP>>>Во-вторых, на C# противоядием от дорогого runtime обхода expression tree является Compiled Queries, так?

EP>>>По твоим словам, "сила" LINQ именно в динамической композиции, а "вся суть" в том что запрос можно по кускам собирать в разных местах, так?
EP>>>Теперь же выясняется что с "с ифами компилировать нет смысла".
G>>Ты читаешь через строку? Я же говорю, что когда запрос сильно динамический, то нет смысла заранее генерить все варианты. Они могут тупо не встретиться в программе,

EP>Можно ли в runtime закэшировать Compiled Query для используемых динамических запросов?

В принципе да. Ты же можешь построить кодом любой Expression Tree.

G>>а время обхода Expression Tree вносит настолько малый вклад в скорость, что даже не заметишь под микроскопом.

EP>Ты же сам говорил про миллисекунды — это же чрезмерно много.
И даже их ты не заметишь в ральном приложении. Bottleneck обычно в другом месте.

EP>>>Вывод напрашивается сам собой — от runtime penalty привнесённой инструментом, трудно избавится (или даже невозможно в ряде случаев) — был бы инструмент построен на иных принципах, этих издержек (или по крайней мере существенной их части) можно было бы избежать — с чего собственно и началась вся ветка.

G>>Каких например?
EP>Издержек? — Тех самых нескольких миллисекунд http://rsdn.ru/forum/flame.comp/6013324.1
Автор: gandjustas
Дата: 13.04.15

И какой в этом смысл? Хорошие индексы позволяют в разы ускорить запросы, кеши на порядок. Кто там будет ради пары мсек возиться? Разве что упоротые C++ники.
Re[29]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 16.04.15 23:11
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>Пусть и не ставилась — мне интересно возможно ли это в рамках C# или нужны внешние инструменты.

G>Да в принципе можно, никто не мешает нагенерить Expression и прогнать все через compiled query.

И как это будет выглядеть? Вместо запросов придётся жонглировать кусками Expression на разных уровнях?

G>>>и то если попадания в кеш не было.

EP>>Какой конкретно cache?
G>Любое серьезное приложение использует application cache, чтобы уменьшить время на передачу по сети и чтение с диска.

По какому ключу обращаться к application cache в случае динамического запроса собирающегося в разных местах?
И при том что один и тот же по структуре динамический запрос в общем случае будет иметь разные аргументы — и соответственно в кэше его не будет

G>А в случае есть еще кеши веб-сервера и клиента.


А как кэш веб-сервера/клиента относится к времени обхода Expression Tree?

G>>>а время обхода Expression Tree вносит настолько малый вклад в скорость, что даже не заметишь под микроскопом.

EP>>Ты же сам говорил про миллисекунды — это же чрезмерно много.
G>И даже их ты не заметишь в ральном приложении. Bottleneck обычно в другом месте.

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

EP>>>>Вывод напрашивается сам собой — от runtime penalty привнесённой инструментом, трудно избавится (или даже невозможно в ряде случаев) — был бы инструмент построен на иных принципах, этих издержек (или по крайней мере существенной их части) можно было бы избежать — с чего собственно и началась вся ветка.

G>>>Каких например?
EP>>Издержек? — Тех самых нескольких миллисекунд http://rsdn.ru/forum/flame.comp/6013324.1
Автор: gandjustas
Дата: 13.04.15

G>И какой в этом смысл? Хорошие индексы позволяют в разы ускорить запросы, кеши на порядок.

А при чёт тут вообще индексы? Речь о том что только на построении запроса теряется несколько миллисекунд.
Или ты хочешь сказать что те кто используют LINQ делают кривые индексы, и соответственно непроизводственный оверхед LINQ'а рояли не играет?

G>Кто там будет ради пары мсек возиться? Разве что упоротые C++ники.


Почему авторы Dapper'а не используют в нём LINQ? У проекта между прочим несколько тысяч звёзд на github'е — а это только те кому не лень было залогиниться и нажать на кнопку.
Всё это "упоротые C++ники", да?
Re[30]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 16.04.15 23:42
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>Пусть и не ставилась — мне интересно возможно ли это в рамках C# или нужны внешние инструменты.

G>>Да в принципе можно, никто не мешает нагенерить Expression и прогнать все через compiled query.

EP>И как это будет выглядеть? Вместо запросов придётся жонглировать кусками Expression на разных уровнях?

Нет, делаешь запросы, а потом через replacevisitor подменяешь параметры и передаешь в compiled query.
Как точно — хз, никто не делал, никому не надо.


G>>>>и то если попадания в кеш не было.

EP>>>Какой конкретно cache?
G>>Любое серьезное приложение использует application cache, чтобы уменьшить время на передачу по сети и чтение с диска.

EP>По какому ключу обращаться к application cache в случае динамического запроса собирающегося в разных местах?

Ключ формируется не на основании запроа к базе, а на основании запроса пользователя. HTTP вообще кеширует по урлу.

EP>И при том что один и тот же по структуре динамический запрос в общем случае будет иметь разные аргументы — и соответственно в кэше его не будет

Увы, объяснить за 5 минут как делать хороший кеш я не могу. Много факторов, но запросы не при чем. Так или иначе количество разных запросов от приложения конечно. Но выписать все их вариации с учетом параметров — невозможно. Кеш нужен для самых частых, это от силы 20%.

G>>А в случае есть еще кеши веб-сервера и клиента.

EP>А как кэш веб-сервера/клиента относится к времени обхода Expression Tree?
Хорошо спроектированние веб-приложение отдает 90% запросов из кеша клиента\reverse proxy, это означает, что до работы с Expression Tree доходит 10%. То есть оптимизировать обход expression tree — бесполезное занятие.

G>>>>а время обхода Expression Tree вносит настолько малый вклад в скорость, что даже не заметишь под микроскопом.

EP>>>Ты же сам говорил про миллисекунды — это же чрезмерно много.
G>>И даже их ты не заметишь в ральном приложении. Bottleneck обычно в другом месте.

EP>Видимо раз разговор поворачивает в такое русло, ты в душе признаешь что LINQ вносит непроизводственные расходы, которых могло бы и не быть в случае более грамотной реализации. Но при этом пытаешься хоть как-то оправдать эти расходы стандартной мантрой "всё в базу упирается"

Я не просто признаю, я говорю что так и есть. Но эти расходы настолько малы, что нет смысла с ними бороться. А ты предлагаешь заменить linq на какое-то говно, чтобы уменьшить затраты, которые никого не интересуют. Довольно глупый подход, тебе не кажется? При чем это говно скорее всего сделает приложение медленнее.
То что все упирается в базу — это факт для корпоративно разработки, ты должен его всегда в голове держать.


EP>>>>>Вывод напрашивается сам собой — от runtime penalty привнесённой инструментом, трудно избавится (или даже невозможно в ряде случаев) — был бы инструмент построен на иных принципах, этих издержек (или по крайней мере существенной их части) можно было бы избежать — с чего собственно и началась вся ветка.

G>>>>Каких например?
EP>>>Издержек? — Тех самых нескольких миллисекунд http://rsdn.ru/forum/flame.comp/6013324.1
Автор: gandjustas
Дата: 13.04.15

G>>И какой в этом смысл? Хорошие индексы позволяют в разы ускорить запросы, кеши на порядок.

EP>А при чёт тут вообще индексы? Речь о том что только на построении запроса теряется несколько миллисекунд.

EP>Или ты хочешь сказать что те кто используют LINQ делают кривые индексы, и соответственно непроизводственный оверхед LINQ'а рояли не играет?
Нет, я хочу сказать, что linq позволяет построить более эффективные запросы, что гораздо важнее, чем пара мсек.

G>>Кто там будет ради пары мсек возиться? Разве что упоротые C++ники.


EP>Почему авторы Dapper'а не используют в нём LINQ? У проекта между прочим несколько тысяч звёзд на github'е — а это только те кому не лень было залогиниться и нажать на кнопку.

EP>Всё это "упоротые C++ники", да?
Исторический фактор. Они начали проект на linq2sql, а он имел серьезные проблемы с быстродействием при обходе больших деревьев, вот и изобрели dapper.
Но сейчас даже EF работает быстрее, а linq2db даже уделывает dapper в скорости маппинга.
Кроме того у парней из SO запросы уже давно стабилизировались и их не надо часто менять. А в корпоративных приложениях изменения происходят постоянно.
Re[31]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 17.04.15 00:07
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>Видимо раз разговор поворачивает в такое русло, ты в душе признаешь что LINQ вносит непроизводственные расходы, которых могло бы и не быть в случае более грамотной реализации. Но при этом пытаешься хоть как-то оправдать эти расходы стандартной мантрой "всё в базу упирается"

G>Я не просто признаю, я говорю что так и есть. Но эти расходы настолько малы, что нет смысла с ними бороться. А ты предлагаешь заменить linq на какое-то говно, чтобы уменьшить затраты, которые никого не интересуют. Довольно глупый подход, тебе не кажется?

А я не предлагал ничего заменять — ни LINQ, ни даже C#. Я лишь констатирую факт того что LINQ делает кучу такой работы, с которой бы успешно справился компилятор — в таком случае LINQ можно было бы применять к более широкому классу задач.

G>При чем это говно скорее всего сделает приложение медленнее.


Так ты определись — либо у LINQ действительно есть непроизводственные расходы, и аналог без этих расходов всегда будет не медленнее, либо же это полезные расходы — но приносят пользу только для части случаев.

EP>>А при чёт тут вообще индексы? Речь о том что только на построении запроса теряется несколько миллисекунд.

EP>>Или ты хочешь сказать что те кто используют LINQ делают кривые индексы, и соответственно непроизводственный оверхед LINQ'а рояли не играет?
G>Нет, я хочу сказать, что linq позволяет построить более эффективные запросы, что гораздо важнее, чем пара мсек.

Более эффективные чем что?
Re[32]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.04.15 00:17
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>Видимо раз разговор поворачивает в такое русло, ты в душе признаешь что LINQ вносит непроизводственные расходы, которых могло бы и не быть в случае более грамотной реализации. Но при этом пытаешься хоть как-то оправдать эти расходы стандартной мантрой "всё в базу упирается"

G>>Я не просто признаю, я говорю что так и есть. Но эти расходы настолько малы, что нет смысла с ними бороться. А ты предлагаешь заменить linq на какое-то говно, чтобы уменьшить затраты, которые никого не интересуют. Довольно глупый подход, тебе не кажется?

EP>А я не предлагал ничего заменять — ни LINQ, ни даже C#. Я лишь констатирую факт того что LINQ делает кучу такой работы, с которой бы успешно справился компилятор — в таком случае LINQ можно было бы применять к более широкому классу задач.

Мы пока не видели чтобы компилятор справлялся с такой работой, не теряя возможностей linq. Компилятор пока справляется только в теории.

G>>При чем это говно скорее всего сделает приложение медленнее.

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


EP>>>А при чёт тут вообще индексы? Речь о том что только на построении запроса теряется несколько миллисекунд.

EP>>>Или ты хочешь сказать что те кто используют LINQ делают кривые индексы, и соответственно непроизводственный оверхед LINQ'а рояли не играет?
G>>Нет, я хочу сказать, что linq позволяет построить более эффективные запросы, что гораздо важнее, чем пара мсек.
EP>Более эффективные чем что?
Чем запросы сделанные без linq.
Re[29]: EntityFramework - тормоз
От: alex_public  
Дата: 17.04.15 04:04
Оценка:
Здравствуйте, Слава, Вы писали:

С>А не получится. Хоть убейся, а когда надо чего-то писать в журналы, транзакционно, то это выглядит как реляционка и является реляционкой, и язык для нее — SQL.


Я какая связь между транзакциями и реляционными БД? Они есть и в nosql БД. Да и вообще много где есть, например в файловых системах.
Re[29]: EntityFramework - тормоз
От: alex_public  
Дата: 17.04.15 05:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

_>>В том, что другие БД ничего не знают про /*+ RESULT_CACHE */. Т.е. если мы делаем движок, который должен работать со многими СУБД, то мы не сможем рассчитывать на эту полезную функцию.

G>Значит функция не такая уж и полезная.

Как раз полезная, т.к. позволяет кэшировать только то, что надо. А в других БД кэшируют всё подряд (что влезает по настройкам кэша).

G>Да, кешироваь в БД неправильно. Каждый мегабайт памяти кеша отбирает мегабайт памяти у пула страниц, что снижает общее быстродействие. Слава богу авторы многих движков СУБД догадалсь не включать эту фичу по умолчанию (ну кроме mysql, он настолько медленный что по другому никак видимо).


Ну да, а кэш в приложение умеет работать не расходуя оперативную память. Видимо тут какая-то магия. )))

_>>Так всё равно непонятно. Какие-то A, B, C... Ты напиши в терминах того нашего примера, что за хитрую проекцию ты хочешь.

G>Не прикидывайся дурачком, все прекрасно ты понял. А если нет, то ты вообще зря тут пишешь.

Давай разберёмся. Ты привёл некий пример на C# и предложил попробовать его повторить. Тебе показали. В ответ ты говоришь, что пример (твой же) не годный и надо его усложнить. Вообще то по всем правилам дискуссии это классический слив. Ну да ладно, сделаем одолжение, опустим этот момент и дадим тебе второй шанс. Но в таком случае давай полный код примера, который надо повторить.

_>>Там у тебя было написано просто "проекция". Если же ты хочешь какие-то join'ы, подзапросы и т.п. с использованием уже готового запроса, то в sqlcpp11 это прекрасно реализовано. Более того, это продемонстрировано в примере, на который я уже раз 10 давал ссылку https://github.com/rbock/sqlpp11/blob/master/examples/select.cpp#L98.

G>Чето он в #if 0 завернут, компилируется вообще?

Да, отлично компилируется. Могу даже показать какой sql он генерирует (там в примере используется некая MockDB, которая просто печатает в консоль sql).

G>А какой смысл динамического запроса, если он всегда приводит к одному и тому же SQL? Его банально можно заменить одной строкой. Интересно как раз тогда, когда одной строкой заменить нельзя или это приведет к потере быстродействия. Мой пример бы именно такой, а ты все пытаешься его свести к более простому случаю.


И в твоём примере и в его аналогах на других языках генерируется разный sql в завимости от рантайм параметров. Что тебе ещё надо?

G>Да лекго:

G>
G>var query = context.Employees;
G>if(cond) query=query.Select(e => new {e.FirstName, LastName=""});
G>else query=query.Select(e => new {e.EmploymentDate, e.LastName});
G>...
G>query=query.Where(...);
G>


G>Но важно как ты это будешь обрабатывать.


И зачем тут LastName=""? ) И какой sql из этого сгенерируется? )

_>>Ну так давай измерим, в чём проблема то? )))

G>Так ты еще ни одного нетривиального запроса не родил. А на тривиальном какой смысл мерить? Там разница будет настолько несущественная, что нет смысла обсуждать.

Будет разница существенная или нет зависит не от сложности запроса, а от времени его исполнения. А оно во многом зависит от объёма базы, индексов, кэширования.
Re[27]: EntityFramework - тормоз
От: itslave СССР  
Дата: 17.04.15 06:30
Оценка: +1
Здравствуйте, gandjustas, Вы писали:
G>Ты читаешь через строку? Я же говорю, что когда запрос сильно динамический, то нет смысла заранее генерить все варианты. Они могут тупо не встретиться в программе, а время обхода Expression Tree вносит настолько малый вклад в скорость, что даже не заметишь под микроскопом.

Года 4 назад тюнил перфоманс одного вполне себе корпоративного приложения. Все ессна уперлось в БД, в которую ходили через EF. Внезапно оказалось что поход в базу через EF на 30% дольше чем plain sql. Как оказалось, оверхед обьяснялся обходом Expression tree и все вылечилось после прикручивания compiled query конкретно в самые критические кейсы (чота порядка 10% от общего количества).
Я категорически за linq и все такое, да и EF наверняка починили с тех времен... но нельзя просто взять и игнорировать производительность
Re[29]: EntityFramework - тормоз
От: alex_public  
Дата: 17.04.15 06:47
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ты откуда свалился? ОРМ тем и занимается что абстрагирует. Любая абстракция над ОРМ — почти всегда ошибка. Тебе никакой C++ не поможет если ты начнешь свои абстракции над IQueryable городить, тормозить будет так, что единственное нормальное решение — выкинуть нафиг эти абстракции. Чем я регулярно и занимаюсь когда меня приглашают починить быстродействие очередной enterprise системы.


G>Речь, конечно, о легковесных ОРМ, которые позволяют таки проекции писать, а не о говне типа Hibernate.


G>ЗЫ. И еще никто и никогда не жаловался на скорость построения SQL из Linq.


Даже настоящие ORM не могут полноценно абстрагировать уровень БД. Потому как очень часто атомарная операция в терминах приложения занимает несколько операций с БД (скажем добавление пользователя, добавляет по строке сразу в несколько разных таблиц). Но кое-что они действительно могут. Типа того жирного фреймворка, на который я кидал ссылку. Только это не имеет никакого отношения к тем библиотекам (sqlcpp11 или эта твоя хрень на базе linq), которые мы тут обсуждаем. Это именно библиотеки работы с SQL базами (отражение sql синтаксис), а не ORM (где вводятся совсем другие операции). Да, а при полноценном абстрагирования слоя работы с БД, движок свободно может работать и с nosql базами или вообще со своими форматами файлов.

Ну а насчёт быстродействия это вообще смешно. Во всяком случае в C++. Там компилятор выкидывает выкидывает вложенности стека вызова десятками (если конечно по глупости не делать всё через виртуальные функции, и то там есть нюансы), так что многоуровневая иерархия схлопывается в линейный код. )))
Re[26]: EntityFramework - тормоз
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 17.04.15 07:13
Оценка: +3
Здравствуйте, alex_public, Вы писали:

_>Ну а в случае sql строк, да, надо ещё вызвать sql_escape_string для параметров


"Эскейпинг" -- ни разу не панацея.
HgLab: Mercurial Server and Repository Management for Windows
Re[30]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.04.15 20:19
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Даже настоящие ORM не могут полноценно абстрагировать уровень БД. Потому как очень часто атомарная операция в терминах приложения занимает несколько операций с БД (скажем добавление пользователя, добавляет по строке сразу в несколько разных таблиц). Но кое-что они действительно могут. Типа того жирного фреймворка, на который я кидал ссылку. Только это не имеет никакого отношения к тем библиотекам (sqlcpp11 или эта твоя хрень на базе linq), которые мы тут обсуждаем. Это именно библиотеки работы с SQL базами (отражение sql синтаксис), а не ORM (где вводятся совсем другие операции). Да, а при полноценном абстрагирования слоя работы с БД, движок свободно может работать и с nosql базами или вообще со своими форматами файлов.

Ты пытаешься с умным видом рассказывать то, что было актуально 10-15 лет назад. Тогда все подряд "пели" про абстрагирование от базы, замену на "свои форматы файлов" итп. Правда термина nosql тогда не было.
Но практика показала обратное. 99% корпоративного софта разрабатывается под конкретную СУБД (иногда с точностью до версии), абстрагирование роняет быстродействие и важно в приложении делать оптимальные запросы. Тот же EF создавался с идеей как ты описываешь, а теперь из него выкидывают все "лишнее", оставляя только генератор запросов и простенький мапинг.
Хотя до сих пор есть упоротые, которые считают что ты всеподряд надо абстрагировать и жирные ORM рулят. Но на практике у них тонны говнокода, все тормозит и логика в хранимках.

_>Ну а насчёт быстродействия это вообще смешно. Во всяком случае в C++. Там компилятор выкидывает выкидывает вложенности стека вызова десятками (если конечно по глупости не делать всё через виртуальные функции, и то там есть нюансы), так что многоуровневая иерархия схлопывается в линейный код. )))

Это ты к чему написал? И кстати как он выкидывает виртуальные вызовы?
Re[28]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.04.15 20:20
Оценка:
Здравствуйте, itslave, Вы писали:

I>Здравствуйте, gandjustas, Вы писали:

G>>Ты читаешь через строку? Я же говорю, что когда запрос сильно динамический, то нет смысла заранее генерить все варианты. Они могут тупо не встретиться в программе, а время обхода Expression Tree вносит настолько малый вклад в скорость, что даже не заметишь под микроскопом.

I>Года 4 назад тюнил перфоманс одного вполне себе корпоративного приложения. Все ессна уперлось в БД, в которую ходили через EF. Внезапно оказалось что поход в базу через EF на 30% дольше чем plain sql. Как оказалось, оверхед обьяснялся обходом Expression tree и все вылечилось после прикручивания compiled query конкретно в самые критические кейсы (чота порядка 10% от общего количества).

I>Я категорически за linq и все такое, да и EF наверняка починили с тех времен... но нельзя просто взять и игнорировать производительность

Сам через тоже самое проходил, это было в EF4, начиная с версии 5 сильно тюнили быстродействие генерации запросов.
Re[30]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.04.15 20:37
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, gandjustas, Вы писали:


_>>>В том, что другие БД ничего не знают про /*+ RESULT_CACHE */. Т.е. если мы делаем движок, который должен работать со многими СУБД, то мы не сможем рассчитывать на эту полезную функцию.

G>>Значит функция не такая уж и полезная.

_>Как раз полезная, т.к. позволяет кэшировать только то, что надо. А в других БД кэшируют всё подряд (что влезает по настройкам кэша).

Так ты определись, какая фича хорошая автоматический кеш или выборочный? С точки зрения утилизации памяти и влияния на overall performance это совершенно разные фичи.

G>>Да, кешироваь в БД неправильно. Каждый мегабайт памяти кеша отбирает мегабайт памяти у пула страниц, что снижает общее быстродействие. Слава богу авторы многих движков СУБД догадалсь не включать эту фичу по умолчанию (ну кроме mysql, он настолько медленный что по другому никак видимо).


_>Ну да, а кэш в приложение умеет работать не расходуя оперативную память. Видимо тут какая-то магия. )))


Кеш приложния легко масштабировать, поставить несколько серверов, подключить redis. С базой так не выйдет.


_>>>Так всё равно непонятно. Какие-то A, B, C... Ты напиши в терминах того нашего примера, что за хитрую проекцию ты хочешь.

G>>Не прикидывайся дурачком, все прекрасно ты понял. А если нет, то ты вообще зря тут пишешь.

_>Давай разберёмся. Ты привёл некий пример на C# и предложил попробовать его повторить. Тебе показали. В ответ ты говоришь, что пример (твой же) не годный и надо его усложнить. Вообще то по всем правилам дискуссии это классический слив. Ну да ладно, сделаем одолжение, опустим этот момент и дадим тебе второй шанс. Но в таком случае давай полный код примера, который надо повторить.

Я пример не усложнял, я сразу написал, что в select может быть что угодно, и джоин, и подзапрос итд. И сразу писал что разные части в разных модулях. Перечитай внимательнее.
Это ты попытался свести пример к более простому случаю, что и есть слив. Я лишь разъяснил тебе несколько раз, что возможности того, что ты продемонстрировал сильно ниже возможностей linq.



_>>>Там у тебя было написано просто "проекция". Если же ты хочешь какие-то join'ы, подзапросы и т.п. с использованием уже готового запроса, то в sqlcpp11 это прекрасно реализовано. Более того, это продемонстрировано в примере, на который я уже раз 10 давал ссылку https://github.com/rbock/sqlpp11/blob/master/examples/select.cpp#L98.

G>>Чето он в #if 0 завернут, компилируется вообще?

_>Да, отлично компилируется. Могу даже показать какой sql он генерирует (там в примере используется некая MockDB, которая просто печатает в консоль sql).

Выложи куданибудь собираемый пример.


G>>Да лекго:

G>>
G>>var query = context.Employees;
G>>if(cond) query=query.Select(e => new {e.FirstName, LastName=""});
G>>else query=query.Select(e => new {e.EmploymentDate, e.LastName});
G>>...
G>>query=query.Where(...);
G>>


G>>Но важно как ты это будешь обрабатывать.


_>И зачем тут LastName=""? ) И какой sql из этого сгенерируется? )

select p1.FirstName, '' as LastName

На клиенте гораздо удобнее когда схема датасета не меняется.
Кстати что у sqlcpp11 с выражениями в запросах?

_>>>Ну так давай измерим, в чём проблема то? )))

G>>Так ты еще ни одного нетривиального запроса не родил. А на тривиальном какой смысл мерить? Там разница будет настолько несущественная, что нет смысла обсуждать.

_>Будет разница существенная или нет зависит не от сложности запроса, а от времени его исполнения. А оно во многом зависит от объёма базы, индексов, кэширования.

А время исполнения не зависит от сложности запроса? Три джоина и семь джоинов будт одинаково выполняться?
Re[31]: EntityFramework - тормоз
От: alex_public  
Дата: 18.04.15 04:08
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ты пытаешься с умным видом рассказывать то, что было актуально 10-15 лет назад. Тогда все подряд "пели" про абстрагирование от базы, замену на "свои форматы файлов" итп. Правда термина nosql тогда не было.

G>Но практика показала обратное. 99% корпоративного софта разрабатывается под конкретную СУБД (иногда с точностью до версии), абстрагирование роняет быстродействие и важно в приложении делать оптимальные запросы. Тот же EF создавался с идеей как ты описываешь, а теперь из него выкидывают все "лишнее", оставляя только генератор запросов и простенький мапинг.
G>Хотя до сих пор есть упоротые, которые считают что ты всеподряд надо абстрагировать и жирные ORM рулят. Но на практике у них тонны говнокода, все тормозит и логика в хранимках.

Ну возможно что во внутрикорпоративном софте и приемлема привязка к одной СУБД. Там собственно и "говнокодить" намного проще, т.к. вообще нет конкуренции (между продукцией). Однако в других областях ситуация совсем другая. В том же веб'е требование работы с произвольной БД является стандартом де факто для любых движков.

Что касается быстродействия, то я уже написал, что это зависит от языка. Хотя сейчас абстрагирования работы с БД принято делать даже на php. Но там от этого могут быть небольшие потери в производительности (хотя поменьше, чем у linq). А вот в некоторых языках (типа того же C++) даже пара лишних уровней абстракции вообще не поменяет итоговый бинарный код. Или в этом есть сомнения?

_>>Ну а насчёт быстродействия это вообще смешно. Во всяком случае в C++. Там компилятор выкидывает выкидывает вложенности стека вызова десятками (если конечно по глупости не делать всё через виртуальные функции, и то там есть нюансы), так что многоуровневая иерархия схлопывается в линейный код. )))

G>Это ты к чему написал? И кстати как он выкидывает виртуальные вызовы?

Ты читай внимательнее. Там написано, что потерь нет как раз в случаях без виртуальных функций. Хотя на самом деле всё не так однозначно. Если допустим у нас в коде будет стоять вызов виртуальной функции для объекта с дочерним (а не базовым) типом, то компилятор может спокойно интерпретировать это как не виртуальный вызов и применить полный набор оптимизаций для обычных функций.
Re[31]: EntityFramework - тормоз
От: alex_public  
Дата: 18.04.15 04:38
Оценка:
Здравствуйте, gandjustas, Вы писали:


G>Так ты определись, какая фича хорошая автоматический кеш или выборочный? С точки зрения утилизации памяти и влияния на overall performance это совершенно разные фичи.


Естественно выборочный, потому как он позволяет разработчику добиться максимальной эффективности. К сожалению в данный момент эта возможность только в одной БД есть, так что её использование неприемлемо в нормальных проектах. А вот использование обычного кэша вполне приемлемо, т.к. он сейчас имеется почти во всех популярных БД.

_>>Ну да, а кэш в приложение умеет работать не расходуя оперативную память. Видимо тут какая-то магия. )))

G>Кеш приложния легко масштабировать, поставить несколько серверов, подключить redis. С базой так не выйдет.

Ага... А синхронизация кэша между серверами не будет ничего стоить. Ну да, ну да. ))) Эта проблема даже на суперкомпьютерах стоит во весь рост (с их мегаскоростью между модулями), а ты хочешь на обычных серверах такое сделать и при этом ещё рассчитывать на какую-то производительность. )))

G>Я пример не усложнял, я сразу написал, что в select может быть что угодно, и джоин, и подзапрос итд. И сразу писал что разные части в разных модулях. Перечитай внимательнее.

G>Это ты попытался свести пример к более простому случаю, что и есть слив. Я лишь разъяснил тебе несколько раз, что возможности того, что ты продемонстрировал сильно ниже возможностей linq.

Что ты там написал потом в тексте не имеет никакого значения. Пример задаётся конкретным кодом, а не словами. И по коду всё было выполнено. В общем, если ты хочешь попытаться ещё разок, то давай конкретный код. Если же нет, то всем будет очевидно, что ты сдался.

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

_>>Да, отлично компилируется. Могу даже показать какой sql он генерирует (там в примере используется некая MockDB, которая просто печатает в консоль sql).

G>Выложи куданибудь собираемый пример.

Так собственно один этот файл — это и есть весь пример целиком. Кстати, и библиотека эта сама не требует какой-то сборки или подключения, т.к. реализована целиком на заголовочных файлах (в лучших традициях Boost'a). Так что просто компилируем один этот файл, обеспечивая ему доступность ко всем его инклудам. )

_>>И зачем тут LastName=""? ) И какой sql из этого сгенерируется? )

G>
G>select p1.FirstName, '' as LastName
G>

G>На клиенте гораздо удобнее когда схема датасета не меняется.

Дааа? ))) А как же ты тогда столько тут распинался в полезности проекций? )
Кстати, а как насчёт накладных расходов на перекидывание никчемных данных между БД и приложением? ) Особенно если в результате запроса будет получаться много строк?

G>Кстати что у sqlcpp11 с выражениями в запросах?


См. всё тот же пример. )))

_>>Будет разница существенная или нет зависит не от сложности запроса, а от времени его исполнения. А оно во многом зависит от объёма базы, индексов, кэширования.

G>А время исполнения не зависит от сложности запроса? Три джоина и семь джоинов будт одинаково выполняться?

Семь джоинов на базе из 10 строк могут исполниться и побыстрее, чем три джоина на базе из 1000 строк. )))

Использование индексов конечно же снижает зависимость от размера БД, но это опять же не в пользу linq, т.к. при быстрых запросах накладных расходы как раз становятся более ощутимы.

А в случае попадания в кэш вообще не будет разницы сколько там джоинов — будет одинаковое время выдачи результата. Более того, в этом случае оно всегда будет настолько маленьким, что накладные расходы от linq будут не просто заметны, а убийственны.
Re[32]: EntityFramework - тормоз
От: Слава  
Дата: 18.04.15 05:02
Оценка:
Здравствуйте, alex_public, Вы писали:

_> В том же веб'е требование работы с произвольной БД является стандартом де факто для любых движков.


Да, и этим движком, единственным, у них является MySql. "Нам не нужно джойнов, нам нужно key-value, потому что наше хранилище их не умеет".
Re[32]: EntityFramework - тормоз
От: Mamut Швеция http://dmitriid.com
Дата: 18.04.15 07:05
Оценка:
_>В том же веб'е требование работы с произвольной БД является стандартом де факто для любых движков.

Для «движков» — да. Только буквально в первый же день использования такого движка приложение, которое на нем строится оказывается строго заточено под один определенный движок. По вполне понятным причинам.


dmitriid.comGitHubLinkedIn
Re[29]: EntityFramework - тормоз
От: Mamut Швеция http://dmitriid.com
Дата: 18.04.15 07:09
Оценка: 1 (1)
EP>>Издержек? — Тех самых нескольких миллисекунд http://rsdn.ru/forum/flame.comp/6013324.1
Автор: gandjustas
Дата: 13.04.15

G>И какой в этом смысл? Хорошие индексы позволяют в разы ускорить запросы, кеши на порядок. Кто там будет ради пары мсек возиться? Разве что упоротые C++ники.

Ээээ. Пара мсек тут, пара мсек там — и вот, заяленный SLA в «все ваши запросы меньше 1 секунды» летят к черту. Мы с этим столкнулись, а мы — упоротые Эрлангисты (ну и Джависты теперь).

Хотя в целом — да. Сначала надо дойти до состояния, когда пара мсек играют роль А до такого реально доходят немногие (единицы единиц процентов, наверное).


dmitriid.comGitHubLinkedIn
Re[26]: EntityFramework - тормоз
От: Mamut Швеция http://dmitriid.com
Дата: 18.04.15 07:15
Оценка:
_>Ну а в случае sql строк, да, надо ещё вызвать sql_escape_string для параметров, но будем считать, что это уже сделано перед нашим примером.

А потом внезапно окажется, чтофункция реализована неверно, и надо делать sql_real_escape_string и т.п.

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


dmitriid.comGitHubLinkedIn
Re[33]: EntityFramework - тормоз
От: alex_public  
Дата: 18.04.15 11:36
Оценка:
Здравствуйте, Слава, Вы писали:

_>> В том же веб'е требование работы с произвольной БД является стандартом де факто для любых движков.

С>Да, и этим движком, единственным, у них является MySql. "Нам не нужно джойнов, нам нужно key-value, потому что наше хранилище их не умеет".

Ээээ, что? ) Берём первый попавшийся из популярных движков https://www.phpbb.com/about/features/ и смотрим в раздел Data Management — видим все популярные базы данных. И такая ситуация не у одного этого движка, а скорее вообще везде. Естественно там, где люди создают продукт и есть конкуренция. А не как с внутрикорпоративным софтом, где можно написать любой говнокод и всё равно получить деньги, лишь бы он соответствовал ТЗ.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.