Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Я ж не от балды теории считаю, как ты, у меня есть статистика по сайтам аналогичной направленности.
Тогда ты, наверно, можешь её показать? Даже если точные цифры — ДСП, то перемасштабировать на миллион. С разбивкой хотя бы по 15-минутным периодам, а лучше 5.
НС> Пиковые нагрузки очень сильно отличаются от средних.
Вот потому и вопрос, что такое пик на таком сайте.
НС> Да и вообще подобные сайты меряют не запросами в секунду, а латентностью.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, ·, Вы писали:
_>>>Ну так и в чём собственно проблема? ) Тебе трудно поставить один if? ) Количество таблиц то не является динамической величиной... ))) _>·>Тебе похоже не трудно, давай тогда код склейки в студию. Ждём, надеемся. _>
_>string query="select ... from ...";
_>if(categoryName||categoryColor||categoryGroupName) query+=" inner join ... ON(...)";//тот самый if
_>query+=" where 1";
_>if(categoryName) query+=" and ...";
_>if(categoryColor) query+=" and ...";
_>if(categoryGroupName) query+=" and ...";
_>
А можно попросить сделать этот код рабочим?
А то идея-то была понятна и до этого. Дьявол начинается при проверке — то скобочку забыли дописать, то оказалось что inner join у нас в одном из вариантов набора параметров после where оказался.
Языком-то все горазды.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>P.S. Хотя в случае C# и желания максимальной производительности скорее всего только вариант голых строк и подходит. Но меня трудно назвать сторонником данного подхода, т.к. я собственно не сторонник самого C#. ))) S>> А как ты относишься к 1С?
_>Никогда не имел дел. Ни как программист, ни как пользователь (руководитель).
_>Слышал только что там своеобразный бухгалерский DSL с кириллическим синтаксисом.
S>>И чем C# хуже питона?
_>Для написания скриптов C# (как и C++) очевидно хуже Питона (надеюсь не надо объяснять почему?). А для других целей я Питон особо и не использую.
Надо. Я могу и на C# писать в стиле скриптов. При этом иметь и типизацию. Я могу сравнивать так как пишу и на 1С и на C#. C# очень приятный язык.
Правда вот синтаксис Nemerle мне больше нравится, но что ж поделать эта дань засилью сишников. S>>Есть языки которые решают конкретные задачи и более удобны по сравнению с другими. S>> Это касается не только написания, но и поддержки кода.
_>Безусловно различные DSL'и гораздо удобнее универсальных языков в своих узких нишах.
А вот C# прекрасно чувствует себя во многих нишах.
и солнце б утром не вставало, когда бы не было меня
_>Изначальный мой тезис (с которого началась вся эта бесконечная дискуссия) звучал так: "ORM на базе Linq — тормоза (относительно аналогичного кода на голых sql строках)". И этот тезис был полностью доказан в теме соответствующими тестами. Дальнейшей же обсуждение свелось к двум слегка холиварным направлениям:
Еще раз в 100200 раз повторю, что запросы могут компилироваться и кэшироваться (если это не динамические запросы). Да и десериализация может компилироваться например с помощью Рослина или деревьев выражений (примеры я тебе уже кучу приводил) . Там много затрат идет на поиск объектов при не использовании AsNoTracking и еще куча подводных камней.
Это будет ничем не медленнее голых SQL строк. Я тебе уже кучу примеров приводил.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
I>>Дотнет, вообще говоря, и предназначался для решения тех проблем, что ты перечислил.
_>Данные "проблемы" легко решает даже самый убогий и древний язычок, при наличие у него всего одной марки компилятора. )))
Типичное дотнет-приложение обычно 2-3 языка, вовсю использует интероп для взаимодействия с системой, вовсю использует бинарные модули писаные на других языках. Более того — обязательно использует нативные модули, как правило, писаные на С++.
И я вот не припомню древних убогих язычков, которые бы умели всё тоже самое.
Здравствуйте, alex_public, Вы писали:
I>>Они заменили на эквивалентный механизм — даппер.
_>Так а как там задаются запросы? )
DSL. Ты же не думаешь, что строки у них в чистом sql ?
I>>Похоже, ты по прежнему уверен, что узкое место это именно сервеный код вызова базы данных
_>Если некие тормоза не являются главными тормозами, то это не означает, что перестают быть тормозами в принципе. )))
Здравствуйте, alex_public, Вы писали:
I>>Включай его ЗП в стоимость решения. За лет 5 денег наберется размером с серьезный сервер.
_>Угу, и каждый месяц в эти 5 лет он будет подключать к новому типу РСУБД, на которую будет резко прыгать проект. ))) Ну да, ну да. )))
Скорее всего это произойдить будет раз в несколько лет. Если вдруг проект перестанет собираться, для него это значит ущерб всему бизнесу.
Новая версия базы выйдет, с новыми плюшками, а может потребуется чтото побольше-побыстрее, что очень вероятно. А может и версия провайдера обновится.
Теперь товарищу придется нанимать сиплюсников, искать их днем с огнем, что бы подобрали очередной ключ к его паззлу.
Здравствуйте, alex_public, Вы писали:
_>·>Видимо я перестал понимать в чём заключается твой тезис. Давай конкретно, проиллюстрируй что и как во время компиляции генерится для Тормознутость и кривость linq в правильных решениях без оверхеда.
_>Изначальный мой тезис (с которого началась вся эта бесконечная дискуссия) звучал так: "ORM на базе Linq — тормоза (относительно аналогичного кода на голых sql строках)". И этот тезис был полностью доказан в теме соответствующими тестами.
Это враньё.
_>1. Насколько данные тормоза критичны для системы целиком. Потому как понятно, что для какого-нибудь бухгалтерского приложение накладные расходы от linq даже не почувствуются. А для систем типа SO наоборот.
Я еще раз напомню, что в SO используется даппер, который уступает по замерам linq2db.
_>2. Возможны ли какие-то решения близкие к linq (т.е. со статической проверкой sql кода, а не в виде sql строк), но без накладных расходов в рантайме. Подобное легко реализуется на любом языке с развитым метапрограммированием. И даже в языке с не самым лучшим МП (типа C++) это тоже вполне реализуемо.
В С++ только за счет ухудшения SQL. Ты даже самый минимум — набор колонок — не сможешь ограничить компилятором, только руками.
Здравствуйте, alex_public, Вы писали:
_>Подобный код можно принять за базу, относительно которой рассчитывать накладные расходы. Причём это на любом языке. А вот потом уже на некоторых языках мы можем попытаться записать тоже самое удобнее, но чтобы при этом не добавлять тормозов.
Неверно при условии "на любом языке". За базу надо брать код в маш-кодах.
_>>>P.S. Это на чистом sql, без всяких удобных библиотечек из C++ (с ними было бы проще, т.к. без всяких строк и лишнего мусора, а просто код вида query.where.add(c.color > categoryColor); ). _>·>И где здесь compile time, нулевой оверхед и в чём отличие от linq? _>Эм, ты реально считаешь, что тормоза linq идут от процесса склейки строк? ) _>Да это практически мгновенные операции на фоне времени исполнения самого запроса. А вот тормоза linq (происходящие от рефлексии) вполне себе сравнимы и даже частенько превосходят время исполнения запроса.
А почему ты всё время говоришь что в linq используется рефлексия? Можно поподробнее где она там используется и для чего? Мои скромные познания .net говорят, что там используется expression tree, который компилируется на ходу в IL, а потом даже может JIT-ится в маш-коды, склеивающие текст запроса.
_>Возможны ли какие-то решения близкие к linq (т.е. со статической проверкой sql кода, а не в виде sql строк), но без накладных расходов в рантайме.
Ты не показал решений без каких-либо накладных расходов в рантайме (Нулевой Оверхед™), или я что-то не знаю и супер-мета-пупер-языки query+=" and ..." умеют выполнять в компайл-тайме? Хочется услышать что конкретно ты называешь накладными расходами.
_>Подобное легко реализуется на любом языке с развитым метапрограммированием. И даже в языке с не самым лучшим МП (типа C++) это тоже вполне реализуемо.
Можно пожалуйста объяснить и показать какая там происходит мета-магия?
Твоё query.where.add() как я понимаю строит дерево выражения (ничего не напоминает?) из контейнеров и палок, которое потом интерпретируется для склейки текста запроса. Можно пояснить за счёт чего интерпретация работает быстрее маш-кодов?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>Ничего подобного. Linq делает не это. Точнее не только это. В начале он анализирует (через тормозную рефлексию) выражение и генерирует из него код склейки и только потом запускает собственно этот код. Причём как раз этот анализ занимает во много раз больше времени, чем собственно склейка строк. И именно оттуда и идут тормоза.
Дерево в Linq анализируется обычно через ExpressionVisitor. С каких это пор для обхода дерева нужна рефлексия?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Примеры на гитхабе полностью компилируемые и исполняемые (собственно было бы странно иначе). Я проверял сам и может проверить любой наш читатель. Так что тут ты уже заврался сверх меры, причём на глазах у всех. G>>Ты предлагаешь тебе на слово поверить? Сделай тесты на этой библиотеке, докажи что не свистишь, заодно и проверим быстродействие.
_>Ну не хочешь верить, возьми уже сам и попробуй скомпилировать и запустить. В чём проблема то? ) Никаких зависимостей там нет (и библиотека сама только в виде заголовочный файлов, если не подключать настоящие СУБД, а ограничиться MockDB), достаточно тупо компилятора C++ и командной строки.
В том то и дело, что без настоящей СУБД не имеет смысла вся эта возня. Поэтому и прошу тебя сделать тесты.
G>>>>Я по-разному пробовал, результат не меняется. _>>>Совсем разучился уже со своим Linq. ))) string query="select ... where "+ship_date?"ship_date=@ship_date":"ship_date is null"; Заметно короче и проще твой страшной хранимки, не так ли? ) И при этом полностью оптимально с точки зрения создания планов... G>>Наконец-то, через 5 постов ты родил строку кода. G>>Надеюсь ты понял какую проблему надо решать.
_>Строка то всем очевидная и я её озвучил только потому, что ты признался что "Я по-разному пробовал, результат не меняется", т.е. что даже такая банальщина тебе уже не по силам. Ну так теперь, когда ты узнал как писать вменяемый код, ты понимаешь что все твои разговоры об оптимизации в той статье были бредовыми? ) Как раз из-за того что ты рассматривал только варианты хранимки vs linq.
Ты хочешь сказать что подобные хранимки никто никогда не пишет, а все клеят строки в прикладном коде? Ты упоротый чтоли?
Как раз склейкой никто не занимается, потому что это ад, а хранимки пишут гораздо чаще, чем это стоит делать.
G>>Теперь от параметра не просто добавляется фильтр, а еще и делается джоин. Без параметров никаких джоинов нет. G>>Сама коллекция product может содержать быть отфильтрована и другими предикатами до фильтра по имени категории. G>>Как это сделать на склейке строк или твоей библиотеке? G>>Как родишь код, подумай что таких параметров на каждый запрос будет десяток. _>Мне не очевидно из данного кода что там за join, зачем он и вообще о чём речь. Или показывай подробнее про задачу, таблицы и т.п. или просто покажи какой генерируется итоговый sql.
Почему тебе не очевидно?
Есть товары и категории, одна категория — много товаров. У нас в каталоге товаров фильтры — один из них по категории. Небольшой кусок кода, который фильтры обрабатывает.
Вообще-то все поняли что я написал, даже те кто с linq не работали.
_>>>Я тебе уже озвучил что мне требуется. ) Пример на C# (для сравнения) работающий с любой вменяемой СУБД (для Linq же это вроде не проблема, не так ли?) С SQL Server я никогда в жизни не встречался и начинать не планирую. ) G>>Ты сейчас вертишься как уж на сковородке чтобы избежать прямого сравнения говноподелки с linq любыми способами. G>>Давай так: G>>1) ты вроде утверждал, что можно с помощью конфига подменить генерацию запросов в коде на C++, чтобы они работали для другой базы
_>Да, для этого мне надо будет подключить в код соответствующий провайдер этой СУБД (как и в linq кстати). Так вот соответствующего развёрнутого провайдера у меня на компьютере нет. Ну и чтобы ты понимал (если не в курсе), в мире C++ библиотеки распространяются в исходниках (хотя бы потому что компиляторы разные и несовместимые), а не в виде бинарника. Т.е. провайдер надо не просто скачать, а ещё и собрать. Причём для его сборки потребуются ещё и какие-то зависимости от производителя СУБД (SDK там какой-нибудь скачать или что-то в этом роде). И у меня нет ни малейшего желания разбираться как оно там делается для данной сомнительной СУБД, которая уж точно мне никогда в жизни не пригодится. )
Понятно. Считаем что говноподелка на C++ медленнее EF пока не доказано обратное.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, gandjustas, Вы писали:
G>>Это должно было стать следующим шагом к пониманию проблемы:
N>И это тоже. N>Вопрос ведь не в конструировании для конкретного случая — его нормальный программист осилит.
Один запрос конечно осилит.
N>Вопросов два: N>1) На каком по счёту таком запросе он обломится и начнёт рисовать фреймворк?
Самый стойкий — на третьем, некоторые начнут рисовать фреймворк еще до первого запроса.
N>2) Если вдруг встало требование конструировать в compile time, как он будет преодолевать комбинаторный взрыв?
Не уверен что это технически возможно вообще при условии, что запросы могут изменяться в будущем.
N>Пока что "ваша" (условно) сторона просто отказывается их рассматривать. Я бы тоже отказался, но мне стало интересно, чего именно добивается коллега alex_public.
Здравствуйте, alex_public, Вы писали:
_>Почему обязательно MySQL? ) Там и PostgreSQL и ещё куча менее известных РСУБД.
Я тебе ведь уже писал — у постгри, по сравнению с большой тройкой, существенно более слабый оптимизатор. Поэтому задача построения качественных запросов для нее становится заметно сложнее и важнее.
Здравствуйте, alex_public, Вы писали:
IT>>Весьма голословное утверждение. Давай посмотрим хотя бы на LINQ в .NET и благодаря ему возможность работы с БД с использованием фактически типизированного SQL.
_>Кстати, весьма тормознутая вещь. Вообще это решение достаточно феерично своей кривизной. Умудриться сделать проверку синтаксиса во время компиляции, но при этом строить sql строки в рантайме на базе тормознутой рефлексии — это просто нечто. )))
Кстати говоря, ты так и не пояснил, где именно ты увидел рефлексию в linq. Построение дерева выражений ? Обход его ? Оптимизация дерева ? Оптимизаця под конкретную базу ? Генерация sql по этому дереву ? Маппинг ?
_>>string query="select ... from ...";
_>>if(categoryName||categoryColor||categoryGroupName) query+=" inner join ... ON(...)";//тот самый if
_>>query+=" where 1";
_>>if(categoryName) query+=" and ...";
_>>if(categoryColor) query+=" and ...";
_>>if(categoryGroupName) query+=" and ...";
_>>
S>А можно попросить сделать этот код рабочим?
Ты имеешь в виду компилируемым? ) Но тогда он будет уже зависеть от особенностей языка и соответствующих библиотек в нём. Так это просто идея была универсальная... Ну да ладно, чтобы не придирались (а то бывают тут неадекваты, которые сразу начнут орать "ааа не можешь", хотя задачка для школьника) покажу пример на той же самой библиотечке C++:
auto q=dynamic_select(db).columns(all_of(Product)).dynamic_from(Product).dynamic_where();
if(categoryName||categoryColor||categoryGroupName) q.from.add(dynamic_join(Category).on(Category.id==Product.category_id));
if(categoryName) q.where.add(Category.name.like(*categoryName+"%"));
if(categoryColor) q.where.add(Category.color==*categoryColor);
if(categoryGroupName) q.where.add(Category.group_name==*categoryGroupName);
S>А то идея-то была понятна и до этого. Дьявол начинается при проверке — то скобочку забыли дописать, то оказалось что inner join у нас в одном из вариантов набора параметров после where оказался.
Нуу в том изначальном примере join после where физически никак не мог оказаться, в любом языке. ))) Ну а в варианте с данной C++ библиотечкой ещё и все скобочки будут проконтролированы компилятором. )
Здравствуйте, alex_public, Вы писали:
_>система может заработать намного быстрее в случае оптимизации простенького, но постоянно используемого запроса.
Для таких запросов существуют CompiledQuery. Там всё закешировано до предела и вполне может состязаться с ручным кодом.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alex_public, Вы писали:
_>Ты хочешь сказать, что при использование linq тебе не потребуется менять своё приложение в случае изменения структуры БД? ) Будет очень любопытно взглянуть на детали реализации подобной магии... ))
Менять придётся. Но в отличии от прямого SQL компилятор C# не позволит проигнорировать изменения даже вроде смены NOT NULL, на NULL, если эти изменения сломают код.
На фразу database refactoring вменяемые девелоперы обычно покручивают пальцем у виска. При использовании linq это становится самым обычным рутинным занятием.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alex_public, Вы писали:
I>>Недавно мы обсуждали замеры производительности. Ты не забыл ? Так вот фокус в том, что linq2db работает быстрее чем dapper. _>Это где ты такое взял? )
Здравствуйте, alex_public, Вы писали:
_>Ты имеешь в виду компилируемым? ) Но тогда он будет уже зависеть от особенностей языка и соответствующих библиотек в нём. Так это просто идея была универсальная... Ну да ладно, чтобы не придирались (а то бывают тут неадекваты, которые сразу начнут орать "ааа не можешь", хотя задачка для школьника) покажу пример на той же самой библиотечке C++: _>
Не прошло и двух месяцев, как ты выдал обещанное, после примерно десятой просьбы. Делаешь успехи.
0 Как быть, если в разных базах запросы имеют разную структуру ? Кто это будет обеспечивать ?
1 Каким образом компилятор гарантирует, что q.where.add не свалится ? Ну, например, в одном месте ты пропустил dynamic_where() а в другом пишешь q.where.add ?
2 Каким образом компилятор гарантирует, что в респонзе будут заполнены все поля, которые нужны для маппинга ?
3 Каким образом компилятор гарантирует, что джойн с Category вообще валидный ?
Фактически, у тебя исключительно проверка синтаксиса и ничего больше. то есть, ровно те же проблемы склейки строк, что были в 90х и от которых всегда всеми силами пытались уйти.
Здравствуйте, Serginio1, Вы писали:
_>>Для написания скриптов C# (как и C++) очевидно хуже Питона (надеюсь не надо объяснять почему?). А для других целей я Питон особо и не использую. S> Надо. Я могу и на C# писать в стиле скриптов. При этом иметь и типизацию. Я могу сравнивать так как пишу и на 1С и на C#. C# очень приятный язык. S>Правда вот синтаксис Nemerle мне больше нравится, но что ж поделать эта дань засилью сишников.
Нуу накидай на C# например скриптик подключающийся параллельно к нескольким удалённым машинам (по ssh), копирующий в них некий проект и собирающий его там. Естественно с выводом всех сообщений об ошибках в локальную консоль. Сравним объём и читаемость твоего решения и решения на Питоне. )
_>>Безусловно различные DSL'и гораздо удобнее универсальных языков в своих узких нишах. S> А вот C# прекрасно чувствует себя во многих нишах.
Естественно, т.к. C# — это не DSL, а полноценный универсальный язык. Хотя всё же набор доступных ему ниш несколько уже чем у большинства нативных языков в силу ограничений самой платформы .net (а точнее clr).