Re[24]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 16.03.18 22:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Совершенно верно. Мы наблюдаем весь стек, сверху донизу. Каждый его фрагмент вроде бы обоснован, и в своей нише работает хорошо. Но в целом получается ерунда — написать хороший масштабируемый и поддерживаемый сервис всё ещё настолько трудно, что об этом прямо каждый раз статьи пишут. И во многом потому, что мы получили решение методом "градиентного спуска": трёхзвенная архитектура хорошо закрепилась, каждый из компонентов съехал в оптимальное для своей роли положение, а пересмотр "парадигмы" — слишком дорогостоящее занятие.


Мы это уже обсуждали.
Вся индустрия промахнулась еще аж в самом начале 2000-х годов, бо рассчитывала на продолжение того бурного роста вычислительных мощностей, который наблюдался примерно от середины 80-х до аккурат 2004-го года. С тех пор натурально упёрлись в железо.


S>Получается, что в случаях, когда традиционная трёхзвенка сливает, разработчики прыгают в сторону и рожают узкозспециальное решение при помощи NoSql, кастомизированных мускулей и апачей, или перепиленного пхп.


Ну, если бы быстродействие процов продолжило так же бешено расти, этого обсуждения не было бы.
И NoSQL не было бы.
И ПХП переводить в нейтив тоже не надо было бы.

Просто сетка уже ускорилась многократно, память ускорилась и увеличилась, хранилища данных уже способны выдавать данные быстрее, чем их можно размещать на шине проца (поэтому и нужны процы с 2-3-4-мя внешними шинами), но сами процы того-с, тормозят.

Раньше ведь было наоборот, когда все современные СУБД разрабатывались.
Тогда тормозила сетка и внешние хранилища, отсюда все принятые инженерные решения.
Помнишь мы обсуждали ~150 циклов чтения в cекунду от силы с магнитного жесткого диска? ))
Сейчас их произвольное кол-во, этих циклов в секунду.


_>>Т.е. речь всё же про некий встраиваемый DSL? А так я в принципе согласен со всеми этими пунктами...

S>В некотором смысле да. Просто нужно понимать, что сервер работает в очень специфическом режиме. Он обрабатывает совместно используемые данные. Пускать туда абстрактный язык общего назначения типа плюсов или паскаля слишком рискованно.

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


S>У них семантика заточена всё же под императивное исполнение и изменяемое состояние.


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


S>Попытки принести в них "СУБДшность" — это transactional memory. Насколько мне известно, особых успехов тут, кроме статеек в научных журналах, нету.


Это аппаратная хрень, поддержанная только в неких процах Sun и по-сути лишь немного раширяет семантику банальных exchange/cas (там их сразу 2 или 4 в одной операции). Т.е., сopy-on-write еще никто не отменял, ничего более "транзакционного" пока не придумали, не смотря на все статьи.


S>Язык по работе с данными должен быть абстрактным ровно в меру. Его идиомы должны позволять легко решать нужные нам задачи, и при этом не порождать адски неэффективный код.


Например, одной из причин неэффективности дотнета является большая косвенность графа объектов в памяти.
Когда эту косвенность нивелируешь, то на обычных целочисленных вычислениях получается не сильное отставание от С++ в среднем (кроме тех случаев, где компилятор еще на этапе компиляции может многое сам подсчитать — для C# это пока недостижимая техника).
Re[36]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.03.18 08:06
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>Тогда зачем ты сюда пишешь если не разобрался?

Я как раз разобрался.
V>Пофик. Речь шла о полном наборе планов.
Этот "полный" набор — очень велик.
V>И если насчёт graph понятно, как ты думаешь, зачем там geometry? Что именно используется?
Неужто для spatial data?
Очередная попытка увести спор в сторону, в надежде наконец-то нащупать топик, в котором оппонент не разобрался?

V>Ты сказал конкретно order, вот и отвечай за order.

V>А натягивать "почти OLAP" я же первый не рекомендовал сразу же, бо там ДРУГОЙ сценарий.
Это не "почти OLAP".
Индексы приходится добавлять и в OLTP, потому что того требует бизнес-логика. Рассуждения про OLAP поскипаны, как нерелевантные.

V>Ну реально, ты такой бежишь размахивать 15-ю индексами.

V>Это для частоизменяемых данных? ))
V>ОМГ...
V>Уволить. Расстрелять.
V>Это не инженерия, это вредительство.
Вот ты сейчас себя каждым постом же всё глубже закапываешь.
Давай посмотрим на учебный пример. Широко известная база ООО "Северный ветер": https://social.msdn.microsoft.com/Forums/sqlserver/en-US/5dac635f-7600-4acc-a2a3-65d4ef310643/indexes-in-northwind?forum=transactsql
8 индексов. Это — учебный пример. В боевой учётной системе будет больше фич, и индексов тоже будет больше.

V>Из которых тяжелый join один, редко два.

Это опять подмена предмета дискуссии. Важна не "тяжесть" join, а количество вариантов планов, которые он порождает.

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

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

V>Кароч, откройте для себя репликацию и OLAP для взрослых.

V>Стоило один раз показать и взрослые люди радовались как малые дети.
Опять фантазии. При мне взрослые люди радовались, как дети, после сокращения времени работы хранимки с 2 часов до 2х минут.
Вот это — да, радость. А предложение им вложиться в отдельные OLAP сервера, и оплатить пять человеко-лет для переписывания существующих клиентов и миграцию данных, вызвало бы у них разве что усмешку.
Нет, я и такие проекты видел, но всем больше нравится "здесь и сейчас".

V>Так вот, в чём суть твоего мухлежа:

Нерелевантная чушь поскипана.

V>Да бывает такая хрень в алгоритмах Uniform Cost Search или Topological Sort.

V>Смирись. ))
Ну ок, то есть всё-таки закладываем неэффективность в corner cases.

S>>Для каждого из них бывает такая комбинация параметров запроса и набора данных в таблице, когда именно этот вариант плана выиграет.


V>Бывает. Но это должен быть запрос соответствующий. А все запросы заранее известны. А таких специфических запросов и 1% не будет.

Каких "таких"? Я говорю про любой запрос с параметрами.
V>Вполне можно настраивать пороги, когда мы еще можем позволить себе генерить код вширь (распространение подстановок), а когда уже хватит.
И в чём будут выражены эти пороги?

V>Похоже, ты не понимаешь, как такие вещи работают.

Пока что никак.
V>Сначала происходит "распознавание" похожих мест — т.е. из вообще всех таблиц и всех запросов.
V>Если интересует конкретно — спроси меня как.
Спрашиваю конкретно — что такое "похожие места", и как нам их распознать статически?
Можно прямо примеры SQL statements, что в них будет "похожего", и как мы сможем это использовать.

V>Вот, опять нечестная манипуляция.

V>Я не верю что ты не понимаешь, что это зависит от конкретного запроса, т.е. где конкретно происходит агрегация и по чему именно происходит join.
V>Т.е. "возрастает" там только в смысле мощности порождаемых языком комбинаций, но никак не в смысле множества вариантов исполнения конкретного такого выражения. Потому для каждого конкретного выражения — многократно падает. Сама операция агрегации отрезает нахрен кучу потенциальных планов, которые имели право на жизнь в отсутствии такой агрегации. Потому что дело не в том "сначала агрегация, потом join", а в том — какие таблицы сначала сканить, именно такой выбор сужается многократно.
Опять какой-то набор слов. Агрегация никак не влияет на порядок сканирования таблиц.
Показываю на пальцах:
select c.Id, c.RegionID, c.CityName, sum(o.TotalAmount) as totalSales from 
  city c inner join customers cs on cs.cityId = c.Id
  inner join orders o on o.customerId = cs.Id
  where o.status = 'SHIPPED'
  group by c.ID, c.RegionID, c.CityName
  having c.RegionID = @RegionID

Здесь можно сначала делать join с city, а потом агрегировать весь поток; а можно cначала всё проагрегировать, а потом join.
Порядок сканирования таблиц вообще может быть произвольным. И оптимальный выбор, в частности, будет зависеть от значения параметра @regionID.
V>Но обсуждается принципиально другая.
Пока что обсуждаются беспочвенные фантазии.

V>Дык, дотнет и джаву ругают как раз за то, что они принципиально не в состоянии производить описанные оптимизации.

V>Поэтому, их бинарник в памяти после джита занимает какое-то совсем уж неприличное кол-во байт, что джаве даже пришлось ввести сборку мусора для кода, ы-ы-ы (привет из 90-х, когда память стоила дороже золота).
Джава ввела сборку мусора для кода потому, что в неё встроена динамическая загрузка. А в дотнете решили что надо выгружать на уровне домена, и только потом под давлением общественности ввели DynamicExpression.
Так что всё ровно наоборот.
V>Скажи, ты знал о том факте, что первые компляторы С++, поддерживающие шаблоны, генерили какой-то совсем уж распухший бинарник?
V>А знал ли ты, что когда компиляторы С++ научились склеивать шаблонный код, то почему-то под этот механизм попал и вовсе не шаблонный, а вообще весь код и это сжало бинарник средней программы (даже без всяких шаблонов) примерно втрое? А знал ли ты, что в сравнении с теми самыми первыми компиляторами с шаблонами но без сжатия, размер генерируемого бинарника ужался более чем на порядок?
Нет, не знал. Пока что не наблюдаю таких чудес. Бинарники, которые генерировались в те времена, когда я писал на плюсах, были около 1 мегабайта. С интересом посмотрю, как их можно упихать в 100к новым компилятором.

V>Так сколько он в среднем даёт планов по одному join?

От четырёх до пары десятков.
V>Давай мы сделаем паузу, пока ты не поймешь этот момент.
Без объяснений — точно не пойму.
Узлы тех планов, которые я видел, невозможно повторно использовать.
То, что я видел про компиляторы С++, было примерно эквивалентно схлопыванию кода дженериков в дотнете, когда для всех ссылочных типов генерируется один и тот же код.
Чудес, которые могут увидеть общность между "тут цикл — и там цикл", и как-то это обыграть, я не встречал.

С нетерпением жду примера двух планов запросов, которые ухитряются что-то повторно использовать друг от друга.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: В России опять напишут новый объектно-ориентированны
От: LaPerouse  
Дата: 18.03.18 00:09
Оценка: :)))
Здравствуйте, Sinclair, Вы писали:

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


T>>Может и тупик, но проблема эта — не проблема ORM. Это проблема языков, которые требуют на любой чих делать отдельный класс.

S>Нет. Это проблема — именно ORM. Потому что без ORM мы на тех же языках работаем с рекордсетами, которые не требуют порождать по классу на запрос. И прекрасно биндим их хоть в UI, хоть в бизнес-логику.
S>ORM претендуют на какую-то помощь, которой по факту не оказывают.

Оказывают, если уметь пользоваться их возможностями. Не имея опыта использования современной ORM (в .net этому опыту взяться неоткуда), весьма неосмотрительно делать такие выводы.

T>>Это и есть кеш, да. Но сущности попадут в кеш независимо от того, как их загрузили — lazy или eager. Поэтому проблема возникает не из-за lazy load.

S>Eager load существует только как костыль к lazy load.
S>Напомню, что в обычном приложении до-ORMной эпохи нет никаких Eager Load — мы просто выполняем запрос и получаем результат. У нас нету "отображаемых объектов" с навигационными свойствами, которые, собственно, и провоцируют кэш, lazy load, и eager load, который должен изображать закат солнца вручную.

Закат солнца вручную будет у тебя, когда ты будешь вручную разруливать идентити объектов, перекладываю их руками из таблицы. ОРМ не делает никакой магии — просто избавляет программиста от рутины написания тысячного по счету однотипного кода перекладывания данных из реляционной модели в объектно-ориентированную.

T>>Да, повлияло, да уронило, да это проблема lazy load, но не та, про которую ты вначале говорил. Когда заранее знаешь, что lazy load мешает — надо включить eager.

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

Как решается эта проблема в plain-sql? Пишется запрос. Как решается эта же проблема в orm? Сюрприз — пишется запрос. Просто во втором случае у нас объектно-ориентированный язык запросов с готовым графом объектов на выходе, без необходимости организовывать тысячный по счету закат солнца руками.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[15]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.03.18 09:42
Оценка:
Здравствуйте, LaPerouse, Вы писали:


LP>Оказывают, если уметь пользоваться их возможностями. Не имея опыта использования современной ORM (в .net этому опыту взяться неоткуда), весьма неосмотрительно делать такие выводы.

Убедительные примеры будут?

LP>Закат солнца вручную будет у тебя, когда ты будешь вручную разруливать идентити объектов, перекладываю их руками из таблицы.

Чегось?
LP>ОРМ не делает никакой магии — просто избавляет программиста от рутины написания тысячного по счету однотипного кода перекладывания данных из реляционной модели в объектно-ориентированную.
Эмм, я пока знаю только одну такую "ORM". Это — linq2sql. Он ровно перекладывает данные. Есть кто-то ещё, без change tracking и lazy load?

LP>Как решается эта проблема в plain-sql? Пишется запрос. Как решается эта же проблема в orm? Сюрприз — пишется запрос. Просто во втором случае у нас объектно-ориентированный язык запросов с готовым графом объектов на выходе, без необходимости организовывать тысячный по счету закат солнца руками.

Убедительные примеры будут?
Покажите, во что на "объектно-ориентированном языке запросов" у нас переписывается plain sql:
select c.Id, c.CityName, sum(o.TotalAmount) as totalSales from 
  city c inner join customers cs on cs.cityId = c.Id
  inner join orders o on o.customerId = cs.Id
  where o.status = 'SHIPPED'
  group by c.ID, c.RegionID, c.CityName
  having c.RegionID = @RegionID

И какого типа будет возвращаемое значение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.03.18 09:57
Оценка:
Здравствуйте, alex_public, Вы писали:
_>Да причём тут лямбды. Вообще помнится близкая к этому вопросу тема уже обсуждалась на этом форуме. И тогда я с ходу предложил простейшее видоизменение условий задачи, от которого решение в стиле linq/sql резко увеличилось в объёме до нечитаемого (про производительность там я вообще молчу), в то время как тупое императивное решение в лоб практически не изменилось. И да, тогда речь шла про коллекции, а не доступ к БД, но в данном случае это не меняет суть. Ну точнее меняет только в том смысле, что я не имею возможности (как раз благодаря промежуточному слою из SQL) сделать аналог того императивного кода при работе с РСУБД.
Ссылка на тот пост сильно бы помогла.

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




_>Безотносительно нашей дискуссии о СУБД, не могу не кинуть тут эту http://en.cppreference.com/w/cpp/language/transactional_memory ссылку — это уже не только статейки, но и уже практически стандарт. А в качестве экспериментальной фичи в том же gcc оно кажется с древней версии 4.7. Но это всё так, к сведению, а не в контексте нашей дискуссии.


_>А остальном согласен со всеми тезисами.


S>>Язык по работе с данными должен быть абстрактным ровно в меру. Его идиомы должны позволять легко решать нужные нам задачи, и при этом не порождать адски неэффективный код.


_>Согласен. А есть какие-то конкретные предложения?

Увы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: В России опять напишут новый объектно-ориентированны
От: LaPerouse  
Дата: 19.03.18 20:31
Оценка: 2 (1)
Здравствуйте, Sinclair, Вы писали:

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


LP>>Оказывают, если уметь пользоваться их возможностями. Не имея опыта использования современной ORM (в .net этому опыту взяться неоткуда), весьма неосмотрительно делать такие выводы.

S>Убедительные примеры будут?

Спрашивай.

LP>>Закат солнца вручную будет у тебя, когда ты будешь вручную разруливать идентити объектов, перекладываю их руками из таблицы.

S>Чегось?
LP>>ОРМ не делает никакой магии — просто избавляет программиста от рутины написания тысячного по счету однотипного кода перекладывания данных из реляционной модели в объектно-ориентированную.
S>Эмм, я пока знаю только одну такую "ORM". Это — linq2sql. Он ровно перекладывает данные. Есть кто-то ещё, без change tracking и lazy load?

Hibernate, eclipselink — две самые распространенные java-orm, при желании там можно этого добиться, только зачем?

LP>>Как решается эта проблема в plain-sql? Пишется запрос. Как решается эта же проблема в orm? Сюрприз — пишется запрос. Просто во втором случае у нас объектно-ориентированный язык запросов с готовым графом объектов на выходе, без необходимости организовывать тысячный по счету закат солнца руками.

S>Убедительные примеры будут?
S>Покажите, во что на "объектно-ориентированном языке запросов" у нас переписывается plain sql:
S>
S>select c.Id, c.CityName, sum(o.TotalAmount) as totalSales from 
S>  city c inner join customers cs on cs.cityId = c.Id
S>  inner join orders o on o.customerId = cs.Id
S>  where o.status = 'SHIPPED'
S>  group by c.ID, c.RegionID, c.CityName
S>  having c.RegionID = @RegionID
S>


На объектно-ориентированном языке запросов JPQL это делается элементарно, красиво, и лаконично, и без всяких убогих cs.cityId=c.Id
(эта информация сидит в описании класса и реализации jpa берет ее оттуда, как и любое другое описание):

select city.id, city.name, sum(o.totalAmount)
from Order o
join o.customer customer
join customer.city city
where o.status='SHIPPED'
group by city.id, city.regionId, city.name
having city.regionId=:regionId


S>И какого типа будет возвращаемое значение.


Какого хочешь. Проще всего так:

List<Object[]> result = em.createQuery(query, Object[].class).getResultList();


Но можно подсунуть любой класс или хештаблицу.
Социализм — это власть трудящихся и централизованная плановая экономика.
Отредактировано 19.03.2018 20:34 LaPerouse . Предыдущая версия .
Re[15]: В России опять напишут новый объектно-ориентированны
От: Danchik Украина  
Дата: 19.03.18 20:34
Оценка:
Здравствуйте, LaPerouse, Вы писали:

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


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



S>>Нет. Это проблема — именно ORM. Потому что без ORM мы на тех же языках работаем с рекордсетами, которые не требуют порождать по классу на запрос. И прекрасно биндим их хоть в UI, хоть в бизнес-логику.

S>>ORM претендуют на какую-то помощь, которой по факту не оказывают.

LP>Оказывают, если уметь пользоваться их возможностями. Не имея опыта использования современной ORM (в .net этому опыту взяться неоткуда), весьма неосмотрительно делать такие выводы.


Есть у меня чувтво что вы EF неподетски освоили. И как там с кастомными функиями, агрегаторами, и другими фичами которые необхоимо в SQL перегнать? По моему недолгому опыту его использования — практически никаких.
Берется и пишется на ровном месте SQL вместо типизированного linq запроса.
А как работать с толпой обьектов? Чтобы что-то удалить, изменить, добавить надо тянуть это с сервера(всю запись). Согласен иногда это нужно, но в преобладающих случаях, это лишний запрос и лишняя загрузка SQL сервера.

T>>>Это и есть кеш, да. Но сущности попадут в кеш независимо от того, как их загрузили — lazy или eager. Поэтому проблема возникает не из-за lazy load.

S>>Eager load существует только как костыль к lazy load.
S>>Напомню, что в обычном приложении до-ORMной эпохи нет никаких Eager Load — мы просто выполняем запрос и получаем результат. У нас нету "отображаемых объектов" с навигационными свойствами, которые, собственно, и провоцируют кэш, lazy load, и eager load, который должен изображать закат солнца вручную.

LP>Закат солнца вручную будет у тебя, когда ты будешь вручную разруливать идентити объектов, перекладываю их руками из таблицы. ОРМ не делает никакой магии — просто избавляет программиста от рутины написания тысячного по счету однотипного кода перекладывания данных из реляционной модели в объектно-ориентированную.


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

T>>>Да, повлияло, да уронило, да это проблема lazy load, но не та, про которую ты вначале говорил. Когда заранее знаешь, что lazy load мешает — надо включить eager.

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

LP>Как решается эта проблема в plain-sql? Пишется запрос. Как решается эта же проблема в orm? Сюрприз — пишется запрос. Просто во втором случае у нас объектно-ориентированный язык запросов с готовым графом объектов на выходе, без необходимости организовывать тысячный по счету закат солнца руками.


Делаю закат солнца руками. Так приятно писать linq запрос который предсказуемо превращается в то что надо, а не во всемогутор SQL, который и соптимизировать уже не дают. Хотя нет — бери и пиши голый SQL.

IMHO, такие ORM как EF, отучают программистов думать как работает SQL сервер, они зачастую не знают SQL — им нужны сущности с деталями и деталями деталей, сначала осортированные, а потом прогруппированные. Надеюсь не надо бьяснять абсурдность сией хотелки.
Или еще лучше: отсортировать, сделать Distinct() и надеятся что записи в нужном порядке.
Re[16]: В России опять напишут новый объектно-ориентированны
От: LaPerouse  
Дата: 19.03.18 20:50
Оценка:
Здравствуйте, Danchik, Вы писали:

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


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


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



S>>>Нет. Это проблема — именно ORM. Потому что без ORM мы на тех же языках работаем с рекордсетами, которые не требуют порождать по классу на запрос. И прекрасно биндим их хоть в UI, хоть в бизнес-логику.

S>>>ORM претендуют на какую-то помощь, которой по факту не оказывают.

LP>>Оказывают, если уметь пользоваться их возможностями. Не имея опыта использования современной ORM (в .net этому опыту взяться неоткуда), весьма неосмотрительно делать такие выводы.


D>Есть у меня чувтво что вы EF неподетски освоили. И как там с кастомными функиями, агрегаторами, и другими фичами которые необхоимо в SQL перегнать? По моему недолгому опыту его использования — практически никаких.

D>А как работать с толпой обьектов? Чтобы что-то удалить, изменить, добавить надо тянуть это с сервера(всю запись). Согласен иногда это нужно, но в преобладающих случаях, это лишний запрос и лишняя загрузка SQL сервера.

Если объекты получать не нужно, то работаешь с ними как хочешь, при помощи того же sql, если criteria api не нравится. У меня есть ощущение, что вы неправильно понимаете назначение инструмента, который пытаетесь использовать. Никто вас не заставляет делать ВСЕ на нем. Внимательно прочитайте три слова, из которых складывается название. Если нет объектов, которые необходимо мапить из строк таблицы, это означает, что вы выходите за область применения этого инструмента (хотя при желании можете его продолжать использовать).

Если нужна типизированность, есть criteria api.

T>>>>Это и есть кеш, да. Но сущности попадут в кеш независимо от того, как их загрузили — lazy или eager. Поэтому проблема возникает не из-за lazy load.

S>>>Eager load существует только как костыль к lazy load.
S>>>Напомню, что в обычном приложении до-ORMной эпохи нет никаких Eager Load — мы просто выполняем запрос и получаем результат. У нас нету "отображаемых объектов" с навигационными свойствами, которые, собственно, и провоцируют кэш, lazy load, и eager load, который должен изображать закат солнца вручную.

LP>>Закат солнца вручную будет у тебя, когда ты будешь вручную разруливать идентити объектов, перекладываю их руками из таблицы. ОРМ не делает никакой магии — просто избавляет программиста от рутины написания тысячного по счету однотипного кода перекладывания данных из реляционной модели в объектно-ориентированную.


D>Это лень, которая в больших проектах приводит к переписыванию сего поделия. Наинклюдают все подряд, получат кучу дополнительных запросов, опять же, чтобы в конце концов, одно поле проапдейтать. А если структура сложная с возможными рекурсиями, так и за голову берутся — оно не взлетает. И начинается борьба с графами, хотя, возможно, вы специалист в борьбе с этим.


Все lazy-зависимости — это детская песочница. Для простых случаев годится, в реальности же нужно использовать запросы. И вот тут мы получаем дикое преимущество orm — писать запросы на специализированном объектно-ориентированном языке намного проще, чем чистый sql. Опять же, смотрим текст выше (про назначение инструмента).


LP>>Как решается эта проблема в plain-sql? Пишется запрос. Как решается эта же проблема в orm? Сюрприз — пишется запрос. Просто во втором случае у нас объектно-ориентированный язык запросов с готовым графом объектов на выходе, без необходимости организовывать тысячный по счету закат солнца руками.


D>Делаю закат солнца руками. Так приятно писать linq запрос который предсказуемо превращается в то что надо, а не во всемогутор SQL, который и соптимизировать уже не дают. Хотя нет — бери и пиши голый SQL.


D>IMHO, такие ORM как EF, отучают программистов думать как работает SQL сервер, они зачастую не знают SQL — им нужны сущности с деталями и деталями деталей, сначала осортированные, а потом прогруппированные. Надеюсь не надо бьяснять абсурдность сией хотелки.


Это проблемы конкретных программистов. Я не использую последние четыре года jpa, потому что вообще редко работаю с бд. Но до этого работал очень плотно и ни разу не имел подобных проблем.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[17]: В России опять напишут новый объектно-ориентированны
От: Danchik Украина  
Дата: 20.03.18 12:11
Оценка:
Здравствуйте, LaPerouse, Вы писали:

D>>IMHO, такие ORM как EF, отучают программистов думать как работает SQL сервер, они зачастую не знают SQL — им нужны сущности с деталями и деталями деталей, сначала осортированные, а потом прогруппированные. Надеюсь не надо бьяснять абсурдность сией хотелки.


LP>Это проблемы конкретных программистов. Я не использую последние четыре года jpa, потому что вообще редко работаю с бд. Но до этого работал очень плотно и ни разу не имел подобных проблем.


Извините не в тему. Хибернейт или что вы там используете, просто в сравнение не идет с тем что можно сделать с Linq провайдерами на .NET
Сравнивать linq c критериа запросами это все равно смотреть на два телевизора — один цветной, второй черно-белый.
Re[18]: В России опять напишут новый объектно-ориентированны
От: LaPerouse  
Дата: 20.03.18 16:07
Оценка:
Здравствуйте, Danchik, Вы писали:

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


D>>>IMHO, такие ORM как EF, отучают программистов думать как работает SQL сервер, они зачастую не знают SQL — им нужны сущности с деталями и деталями деталей, сначала осортированные, а потом прогруппированные. Надеюсь не надо бьяснять абсурдность сией хотелки.


LP>>Это проблемы конкретных программистов. Я не использую последние четыре года jpa, потому что вообще редко работаю с бд. Но до этого работал очень плотно и ни разу не имел подобных проблем.


D>Извините не в тему. Хибернейт или что вы там используете, просто в сравнение не идет с тем что можно сделать с Linq провайдерами на .NET


Рад за вас. Только при чем тут Linq?

D>Сравнивать linq c критериа запросами это все равно смотреть на два телевизора — один цветной, второй черно-белый.


А ты пробовал не сравнивать, а работать?
ORM позволяет решать задачи эффективнее, чем plain sql. Linq в качестве примера приводить не нужно, в ява он отсутствует, а его аналоги (jooq) сильно проигрывают существующим имплементациям jpa.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[36]: В России опять напишут новый объектно-ориентированны
От: LaPerouse  
Дата: 20.03.18 16:25
Оценка:
Здравствуйте, vdimas, Вы писали:


V>Так вот, в чём суть твоего мухлежа:

V>- для оперативных данных много индексов не надо, их обычно ровно 3 во всех перечисленных типах систем (для упомянутой основной таблицы движений);

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

V>- для исторических данных не надо много динамических планов, бо данные неизменяемые, индексы априори пересчитаны, как я предлагал т.н. "профилирование по реальным данным" — оно вполне может быть частью операции "закрытие периода" — это одна из самых важных операций ЛЮБЫХ учётных систем более-менее серьезного уровня.


Индексы пересчитаны, но они огромные, и условия могут меняться. Про такую вещь, как partitioning, слышал?
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[19]: В России опять напишут новый объектно-ориентированны
От: Danchik Украина  
Дата: 20.03.18 16:35
Оценка:
Здравствуйте, LaPerouse, Вы писали:

D>>Извините не в тему. Хибернейт или что вы там используете, просто в сравнение не идет с тем что можно сделать с Linq провайдерами на .NET


LP>Рад за вас. Только при чем тут Linq?


Также как при чему тут Java. Думал вы на .NET работаете, вижу что нет.

D>>Сравнивать linq c критериа запросами это все равно смотреть на два телевизора — один цветной, второй черно-белый.


LP>А ты пробовал не сравнивать, а работать?

LP>ORM позволяет решать задачи эффективнее, чем plain sql. Linq в качестве примера приводить не нужно, в ява он отсутствует, а его аналоги (jooq) сильно проигрывают существующим имплементациям jpa.

Как решать так и создавать проблемы.
Только не зная что нам дает linq я тут буду долго бится об стенку обьясняя его преимущества.
Тот же jooq продвигается, но опять же он далеко от linq и возможностей декомпозиции запросов. Ве-таки это весьма мощное расширение языка, и просто либой его не покроешь.
Re[37]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 20.03.18 17:59
Оценка: :)
Здравствуйте, LaPerouse, Вы писали:

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


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

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


V>>- для исторических данных не надо много динамических планов, бо данные неизменяемые, индексы априори пересчитаны, как я предлагал т.н. "профилирование по реальным данным" — оно вполне может быть частью операции "закрытие периода" — это одна из самых важных операций ЛЮБЫХ учётных систем более-менее серьезного уровня.

LP>Индексы пересчитаны, но они огромные, и условия могут меняться.

Огромные или нет индексы — не принципиально.
Я предлагал статически генерить следующее:
— код, оценивающий некий план;
— код. исполняющий этот план.

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

Например:
float calcWeght_ScanByIndex_Table1_Index1(int value);


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

Еще:
float calcWeght_ScanByIndex_Table1_Index2_Range(DateTime minValue, DateTime maxValue);

Думаю, смысл понятен.

В любом случае всё мн-во планов для реальных запросов базой сегодня генерится. Просто не в момент компиляции, а в момент работы.
Если этих планов совсем уж много — их можно разбить на подгружаемые модули. Модули в С++, в отличие от дотнета, можно загружать и выгружать динамически, т.е. вполне можно содержать тоже некий кеш планов, просто не динамически сгенерённых, а статически.
Отредактировано 20.03.2018 21:58 vdimas . Предыдущая версия . Еще …
Отредактировано 20.03.2018 21:57 vdimas . Предыдущая версия .
Re[26]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 21.03.18 13:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Да причём тут лямбды. Вообще помнится близкая к этому вопросу тема уже обсуждалась на этом форуме. И тогда я с ходу предложил простейшее видоизменение условий задачи, от которого решение в стиле linq/sql резко увеличилось в объёме до нечитаемого (про производительность там я вообще молчу), в то время как тупое императивное решение в лоб практически не изменилось. И да, тогда речь шла про коллекции, а не доступ к БД, но в данном случае это не меняет суть. Ну точнее меняет только в том смысле, что я не имею возможности (как раз благодаря промежуточному слою из SQL) сделать аналог того императивного кода при работе с РСУБД.

S>Ссылка на тот пост сильно бы помогла.

Ну даже не знаю как её найти. Это было лет 5 назад, так что я и официального заголовка темы не помню. Однако я помню сам принцип, так что могу легко повторить тебе сейчас тот свой пример.

Значит тогда обсуждалось сравнение традиционной работы с контейнерами и linq. И какой-то из любителей Linq гордо предложил задачку для сравнения. Типа такой: есть файл, состоящий из набора строк, каждая из которых представляет собой набор чисел, разделённых запятой (ну в общем что-то типа csv), и требуется вывести отсортированный список значений, каждое из которых является суммой (или какой-то ещё операцией — не суть) чисел на каждой строке, но при этом строка учитывается только при условии что элементов ней больше некого числа. Ну и кажется было ещё условие (фильтр) на сами числа, в общем не суть. С помощью linq данную задачку очень красиво решили в несколько строчек. Ну а тупое императивное решение было действительно несколько более громоздким.

А потом я предложил всего лишь чуть-чуть изменить условия фильтрации: строка берётся в том случае, если у предыдущей строки (а не у неё) элементов больше заданного и фильтр по самим числам тоже в зависимости от значения предыдущего числа. И после этого началось веселье. В начале большинство фанатов linq просто тупо рассосалось из темки. Но потом один герой (это я без иронии) всё же сумел представить решение, которое представляло из себя страшного и запутанного (решение было на базе zip'ов и т.п. конструкций) монстра чуть ли не на страницу кода. Помнится до тестирование его быстродействия (а это было одним из предметов дискуссии в той темке) так даже и не дошло. И да, в тупом императивном решение при данном изменение условий задачи поменялось всего несколько букв.

Так что linq/sql подход — это всё же явно не идеал даже для работы с обычными таблицами. Что уж говорить про разные графы, документы и т.п.

P.S. Конечно же в некоторых РСУБД есть встроенные средства для решения указанной проблемы. Но во-первых они все не входят в стандарт SQL (я уже не говорю про linq), а во-вторых выглядят как откровенные костыли. Всё же проблема тут именно концептуальная, а не в наличие/отсутствие подходящей функции/оператора.
Re[27]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.03.18 16:47
Оценка: 2 (1) +1
Здравствуйте, alex_public, Вы писали:
_>Значит тогда обсуждалось сравнение традиционной работы с контейнерами и linq. И какой-то из любителей Linq гордо предложил задачку для сравнения. Типа такой: есть файл, состоящий из набора строк, каждая из которых представляет собой набор чисел, разделённых запятой (ну в общем что-то типа csv), и требуется вывести отсортированный список значений, каждое из которых является суммой (или какой-то ещё операцией — не суть) чисел на каждой строке, но при этом строка учитывается только при условии что элементов ней больше некого числа. Ну и кажется было ещё условие (фильтр) на сами числа, в общем не суть. С помощью linq данную задачку очень красиво решили в несколько строчек. Ну а тупое императивное решение было действительно несколько более громоздким.

_>А потом я предложил всего лишь чуть-чуть изменить условия фильтрации: строка берётся в том случае, если у предыдущей строки (а не у неё) элементов больше заданного и фильтр по самим числам тоже в зависимости от значения предыдущего числа. И после этого началось веселье. В начале большинство фанатов linq просто тупо рассосалось из темки. Но потом один герой (это я без иронии) всё же сумел представить решение, которое представляло из себя страшного и запутанного (решение было на базе zip'ов и т.п. конструкций) монстра чуть ли не на страницу кода. Помнится до тестирование его быстродействия (а это было одним из предметов дискуссии в той темке) так даже и не дошло. И да, в тупом императивном решение при данном изменение условий задачи поменялось всего несколько букв.

Это да. В реляционной модели (для работы с которой и проектировался линк) нет понятия "предыдущей строки". Кортежи предполагаются независимыми, поэтому готовых методов работы нету.
Это один из классических вопросов на собеседовании DBA — "есть таблица из двух полей — ДатаНачала, ОписаниеСобытия. Выведите эту таблицу, добавив ДатуОкончания — она равна ДатаНачала для следующего события; для последнего события должна быть равна GetDate()".
На более-менее стандартном SQL это выглядит конечно же страшно (см.тж.CTE). Хорошая новость — в том, что взрослые СУБД умеют такое оптимизировать, и обходятся одним сканированием таблицы.
_>Так что linq/sql подход — это всё же явно не идеал даже для работы с обычными таблицами. Что уж говорить про разные графы, документы и т.п.
А вот на linq на самом деле ничего военного нет — он же часть языка общего назначения. Я могу легко определить функцию
public IEnumerable<CurrentPrev<T, T>> PairScan(this IEnumerable<T> source)
{
   var e = source.GetEnumerator();
   if (!e.MoveNext())
     yield break;
   var prev = e.Current;
   while(e.MoveNext())
   {
     yield return new CurrentPrev(){Current = e.Current; Previous = prev};
     prev = e.Current;
   }
}

После этого задачка становится тривиальной.
var q = from s in source.PairScan() where s.Previous.Length > MinLength && s.Current.Length > MinLength select (здесь то выражение, которое там от чего-то зависит)

В нормальных СУБД примерно то же строится при помощи table-valued function, и весь ужос-ужос тоже прячется под капот, позволяя поверх него наворачивать дополнительные условия.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[37]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 21.03.18 21:08
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

S>Вот ты сейчас себя каждым постом же всё глубже закапываешь.


Прекрасное начало, бой барабанов, тра-та-та-та-та...


S>Давай посмотрим на учебный пример. Широко известная база ООО "Северный ветер": https://social.msdn.microsoft.com/Forums/sqlserver/en-US/5dac635f-7600-4acc-a2a3-65d4ef310643/indexes-in-northwind?forum=transactsql

S>8 индексов. Это — учебный пример.

Это не таблица движений.
(смайла для иллюстрации эпик фейла такого масштаба еще не придумано)

Собсно, первая моя поделка примерно такого уровня и была — куча документов, а отчётность сводилась как union из кучи таблиц.


S>В боевой учётной системе будет больше фич, и индексов тоже будет больше.


В боевой системе мухи отдельно, котлеты отдельно.
Таблица движений лишь ссылается на свой документ-источник.
Re[27]: В России опять напишут новый объектно-ориентированны
От: IT Россия linq2db.com
Дата: 22.03.18 01:40
Оценка:
Здравствуйте, alex_public, Вы писали:

_>А потом я предложил всего лишь чуть-чуть изменить условия фильтрации: строка берётся в том случае, если у предыдущей строки (а не у неё) элементов больше заданного и фильтр по самим числам тоже в зависимости от значения предыдущего числа.


Это от недостатка опыта у подопытных пять лет назад. Сегодня такие задачки нашустрились решать элементарно с помощью того же императива и yield return. В смысле необходимый функционал типа "в зависимости от значения предыдущего числа" легко реализуется вспомогательными расширениями.

ЗЫ. Сам по себе трёп linq vs императив считаю бестолковым и местами туповатым, примерно как FP vs OOP, отвёртка против молотка. Оно не должно быть не одно против другого, оно должно быть вместе и дополнять.
Если нам не помогут, то мы тоже никого не пощадим.
Re[28]: В России опять напишут новый объектно-ориентированны
От: IT Россия linq2db.com
Дата: 22.03.18 01:47
Оценка: :))) :)
Здравствуйте, Sinclair, Вы писали:

S>А вот на linq на самом деле ничего военного нет — он же часть языка общего назначения. Я могу легко определить функцию


Блин, мог бы и промолчать. Всмысле я. Если бы сначала дочитывал весь типик до конца, а потом отвечал
Если нам не помогут, то мы тоже никого не пощадим.
Re[38]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.03.18 05:28
Оценка: :)
Здравствуйте, vdimas, Вы писали:

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


S>>Вот ты сейчас себя каждым постом же всё глубже закапываешь.


V>Прекрасное начало, бой барабанов, тра-та-та-та-та...



S>>Давай посмотрим на учебный пример. Широко известная база ООО "Северный ветер": https://social.msdn.microsoft.com/Forums/sqlserver/en-US/5dac635f-7600-4acc-a2a3-65d4ef310643/indexes-in-northwind?forum=transactsql

S>>8 индексов. Это — учебный пример.

V>Это не таблица движений.

Это та самая таблица orders, которая обычно сидит в середине star join
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: В России опять напишут новый объектно-ориентированны
От: Ночной Смотрящий Россия  
Дата: 22.03.18 05:58
Оценка: +4
Здравствуйте, LaPerouse, Вы писали:

LP>Какого хочешь. Проще всего так:

LP>
LP>List<Object[]> result = em.createQuery(query, Object[].class).getResultList();
LP>


Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.