Здравствуйте, alex_public, Вы писали:
_>Вот с чего вы все берёте то подобный бред? ) Вроде же было чётко сказано, что в отличие от Linq данный инструмент является точным отражением SQL.
И чо? Он от этого сразу стал удобнее?
_>Или же ты хочешь сказать, чтобы ты бы написал подобный (с кучей вложенных селектов) sql запрос сам? )))
Ты опять чего то не понял, что, вобщем, с тобой регулярно происходит. Есть запрос, который пишет человек. А есть механика, которая получает с клиента выбранные сортировки, фильтры и страницы в гриде. Задача — автоматически сделать так, чтобы в грид отправились только нужные для отображения данные. Написать все вариации запроса руками нереально — комбинаций их целая куча. А склейка на говнорешениях вроде твоего sqlpp — как раз и дают те самые тормоза, о которых ты тут страдаешь.
И при этом у тебя еще хватает наглости обвинять собеседников в том, что они sql не знают
Здравствуйте, Ночной Смотрящий, Вы писали:
_>>Вот с чего вы все берёте то подобный бред? ) Вроде же было чётко сказано, что в отличие от Linq данный инструмент является точным отражением SQL. НС>И чо? Он от этого сразу стал удобнее?
Ну кому-то удобнее, кому-то нет. Это дело вкуса и привычек. Лично мне для обращения к РСУБД синтаксис sql кажется вполне удобным.
_>>Или же ты хочешь сказать, чтобы ты бы написал подобный (с кучей вложенных селектов) sql запрос сам? ))) НС>Ты опять чего то не понял, что, вобщем, с тобой регулярно происходит. Есть запрос, который пишет человек. А есть механика, которая получает с клиента выбранные сортировки, фильтры и страницы в гриде. Задача — автоматически сделать так, чтобы в грид отправились только нужные для отображения данные. Написать все вариации запроса руками нереально — комбинаций их целая куча. А склейка на говнорешениях вроде твоего sqlpp — как раз и дают те самые тормоза, о которых ты тут страдаешь.
Что-то ты какую-то ерунду говоришь) Формирование sql строки под данную задачку на любом вменяемом языке (в том числе и на C#) записывается в 2-3 строки. ) Даже какой-то крутой библиотечки не надо. Хотя с ней конечно приятнее, т.к. она проконтролирует корректность во время компиляции.
Здравствуйте, gandjustas, Вы писали:
G>>>Бред. Кэш не становится базой. Сценарии использования разные от слова вообще. C>>Ещё как становится. G>Хотя бы обосновать свои слова можешь? А лучше доказать.
Да очень просто. 100500 сайтов через это прошли — при росте загрузки начинаются: "А что если мы поменяем данные в кэше, вместо того, чтобы их инвалидировать, а то база умирает?"
Потом туда добавляется: "Ну так у нас в кэше все данные лежат, давайте мы тут тупой цикл воткнём вместо сложного запроса!"
Ну и через три-четыре шага оказывается, что кэш становится полноценной БД.
C>>Правильный кэш всё может. В частности: запросы, в том числе и сложные, гарантию целостности данных (транзакционный лог, репликация с eventual consistency и т.д.). G>И скорость при этом выше, чем у RDBMS при одинаковом объеме данных? Что за магический движок такой?
Конечно. Например, Cassandra.
G>Почитай старые посты на coding horror, там много почему SO сделан был именно так. По сути две причины — asp.net mvc и linq2sql.
И что? А Github вот на Ruby-on-Rails написан. А FaceBook вообще на PHP.
C>>Если заниматься крупным масштабом, то там просто никак кроме как с Линуксом не получается. Даже у MS, что самое смешное. G>SO доказывает обратное. Это крупный масштаб. 99% проектов меньший масштаб имеют.
SO — это примерно средний масштаб. Даже у меня крупнее по количеству запросов в секунду и объёму данных.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Ну да, linq2db конечно получше, всего 100% накладных расходов, а не 500%. ))) G>>Да хоть 10000%, относительные величины не имеют никакого смысла. G>>Имеет смысл влияние скорости linq на время ответа и пропускную способность. Причем в реальном приложении, а не синтетическом тесте.
_>Похоже что уже не имеет смысла продолжать дискуссию с тобой, т.к. от тебя пошла исключительно демагогия и отмазки. Вот на 100% уверен, что если бы тесты показывали бы преимущество linq решений, то ты бы тут соловьём пел о необходимость верить только тестам. )))
Ты обвиняешь меня в демагогии, аргументируя собственными фантазиями? Сильный прием, я запишу.
_>>>Ну даже если забыть о нормальных реализация уже давно имеющихся в других СУБД, то хотя бы из того, что они исправили это в 2012-ом году. ))) Причём реализовав как раз как у других было. G>>Ок, если ты настолько глуп — объясняю. G>>SQL Server очень хорошо следует стандартам. _>Хороший юмор. Это "top x" у нас соответствует стандарту, да? ) Да и вообще MS славится своим отношением к стандартам во всём. )))
Не следует. И что? Кто-то говорил о 100% соблюдении стандарта? Это неразумно, стандарт во многом не учитывает реальные кейсы.
G>>В стандартах ANSI не было (и насколько я знаю до сих пор нету) штатного способа разбиения резалтсета на страницы. Было через курсоры, но реализация курсоров оказывается медленнее операций с множествами. _>Ну вот теперь и проявляется кто у нас на самом деле не знаком с SQL, а знаком исключительно с конкретной поделкой одной известной компании. Хотя я в общем то совсем не удивлён — почти всегда те, кто громче всех кричит о незнание других, на самом деле сами не особо разбираются. Тут таких много на форуме... _>В стандарте SQL2008 оно появилось.
Да-да и в каком виде?
G>>Поэтому в T-SQL долго не включали операторы постраничного разбиения. А вот ranking functions как раз в стандарте есть и через них прекрасно делается разбиение на страницы. G>>Только в конце 2000-х стало очевидно, что на стандарт уже все положили болт и тогда добавили операторы в T-SQL. _>Зачем врать то? ) Появилось оно не в конце 2000-ых, а вполне себе в 2012, т.е. через несколько лет после появления в стандарте. И через десятилетие после того, как этим спокойно работали пользователи нормальных СУБД.
Ты наверное не понимаешь, что для того, чтобы что-то появилось в 2012 это надо было делать в 2008. Спецификации к следующей версии пишутся сильно заранее до релиза.
_>>>У тебя мозг уже не способен связать два последовательных абзаца? ) Перечитай ещё пару разу предыдущий абзац))) G>>Ок, давай возьмем современные версии двух движков и ты на примере покажешь чем pl\sql в Postgres кардинально отличается от T-SQL. Ты не сможешь этого сделать. Поэтому все твои рассуждения — бредятина.
_>Похоже тебе надо ещё раз 10 перечитать тот абзац. ) Речь как раз и шла о том, что только в 2012-ом SQL Server приблизился к нормальным решениям. Т.е. речь шла о сравнение не современных решений, а предыдущих лет.
Слушай, ты как маленький. постраничная разбивка результатов никаких проблем никому не приносила с 2008 года. Это толко у тебя с этим были какие-то проблемы. Также как и со скоростью linq впрочем.
_>А вот сейчас похоже можно уже и с SQL Server без linq нормально жить.
Ты сам начал разговор, с того, что SQL Server — хреновая СУБД и есть гораздо лучше. Вот обоснуй свои слова. Сейчас 2016 год если что.
15 лет назад все СУБД были говном по сравнению с сегодняшними версиями.
G>>Ты просто не понимаешь о чем они пишут. G>>Они тебе говорят что для разных движков и даже разных версий одного движка одно и то же логическое выражение может быть записано по разному и давать разное быстродействие. Это означает, что в compile-time ты не сможешь сгенерировать оптимальный запрос к БД в принципе, а в runtime это можно сделать.
_>До тебя так и не дошло? ) Генерируется во время компиляции не сам запрос, а код его создания (склейки строк). Собственно иначе и невозможно, т.к. в запрос входят данные.
Как до тебя не дошло, что строки могут получиться кардинально разными?
Берем то же разбиение по страницам. До 2012 SQL Server тебе нужен был подзапрос с row_number, после 2012 подзапрос не нужен.
Теперь покажи пример кода, который будет сгенерирован, чтобы поддерживать эти кейсы.
G>>Я тебе говорю о том, что даже в рамках одного движка linq с легкостью сгенерирует сотни похожих запросов и каждый будет оптимальным для своего сценария, а руками даже десять таких запросов написать и поддерживать невозможно.
_>Даже если не использовать готовую библиотечку генерации во время компиляции (типа обсуждаемой), то это всё равно не означает что надо каждый запрос прописывать руками. Ты там со своим linq похоже совсем уже забыл, что есть банальные операции со строками, функциям можно параметры передавать и т.п..
Конечно забыл это как страшный сон. В 2006 году у меня был проект с кучей склеек строк, багов было огромное количество, поддерживать это было невозможно.
Я прошел через это, а ты только теоретизируешь.
_>>>Да да, конечно не может. И написать код, генерирующий эти запросы он тоже не может. ))) G>>Если сможет, тогда у него получится linq. Или придется жертвовать выразительной силой, получая в итоге более универсальные и более тормозящие запросы. Ты же так и не смог показать генератор запросов, аналогичный linq по мощности, но без оверхеда.
_>Помнится в той старой темке ты говорил тоже самое (и даже ещё смешнее, что типа банальных join, groupby и т.п. нет). Но когда тебя ткнули в нос в соответствующие работающие примеры (причём даже не на форуме, а прямо в папке example той библиотечки, в которую ты сам не догадался заглянуть), то по тихому слился из дискуссии. Если сейчас попробовать повторить тоже самое, то не сомневаюсь в аналогичном результате.
Примеры не были работающими никогда, их невозможно было нигде запустить, чтобы банально проверить качество генерируемого sql. Я тебе и тогда предлагал превратить их в работающие, прогнать на сценариях с проекциями (самыми важными по сути), но ты слился, как и сейчас.
_>>>Это если запрос написать полностью аналогичный процедуре. Что сделает разве что какой-то альтернативно одарённый программист. G>>Ты опять не понимаешь что тебе пишут. Почитай чтоли мануалы на досуге. Если взять один и тот же запрос и завернуть его в процедуру или вызывать текстом из кода, то в подавляющем большинстве случаев они будут исполняться абсолютно одинаково. _>А ты даже читать не умеешь похоже. Ответить на фразу "одинаково только если запрос написать полностью аналогичный процедуре, что бредово" фразой "если взять один и тот же запрос, то будет одинаков" может только реальный уникум.
Тогда потрусь объясни что ты имеешь ввиду? Ты же у нас одаренный а плане SQL, иногда такие перлы выдаешь, что лучше не читать.
_>>>Повторяю по слогам. Ты показал linq код, делающий запрос на базе C# переменной. При этом аналогом его у тебя была некая абстрактная хранимка, висящая в воздухе, а не соответствующий C# код (без linq, на голом sql) делающий аналогичное из той же переменной. Попробуй его написать и может до тебя дойдёт о чём речь. G>>Ты хочешь сказать, что надо подставлять параметр в текст запроса, а не использовать механизм параметров?
_>Вообще то и при использование параметров нормальный запрос будет выглядеть короче твоего чудища в хранимке. И при этом работать оптимизировано. Попробуй сам написать такое и увидишь. Или ты уже совсем разучился с этим своим linq и нужна подсказка? )
Я по-разному пробовал, результат не меняется.
G>>Ты опять показал свой профанизм. G>>Подстановка параметров имеет два огроменных недостатка: G>>1) SQL-инъекции в случае текстовых параметров, они гарантированно будут. Надежного метода экранирования практически нет. _>
Сказать нечего, понятно.
G>>2) Каждый запрос будет компилироваться по новой. Это мееедленно и кушает память базы на хранение планов. G>>С твоим подходом быстродействие упадет и приложение станет более уязвимым. G>>Так что брось сразу эту затею и читай мануалы.
_>О, я смотрю что незнание проявляется всё больше и больше. Причём здесь уже включает даже твой любимый sql server, а не только сам язык sql. Похоже что ты слышал только о кэширование планов параметризованных программистом запросов. А о просто кэширование планов или об автопараметризации констант ты и не слышал видимо. Мда... )
Похоже ты только слова слышал, но смысла их не понимаешь.
1) Все движки БД компилируют запросы и кешируют планы
2) Если клеить строки с константами, то планов будет много и много времени уйдет на компиляцию. Из-за этого тормозит.
3) Почти во всех базах есть автопараметризация, когда в простых запросах подстановка заменяется параметром и компилируется параметризованный запрос и только один раз. Любой запрос с джоином простым не является.
4) Любой параметризованный запрос страдает от parameter sniffing problem.
5) Победить psp, где она имеет большой impact, можно через генерацию разных запросов для сочетаний параметров с разной селективностью. Чаще всего это нужно, когда в зависимости от присутствия параметра надо фильтровать таблицу.
6) С точки зрения программы надо клеить строки. Тут два варианта — руками или использовать linq. Руками — чревато ошибками, сложности с рефакторингом и поддержкой.
В каком месте этой цепочки ты хочешь обмануть реальность?
_>>>А какая разница в какой компании написан софт? ) Мы же языки/платформы/библиотеки обсуждаем... G>>Не знаю что ты обсуждаешь, а меня инересуют что делают парни из SO. G>>Парни из SO пишут код на C# и запускают его под вендой. А сторонние продукты запускают по nix потому что это дешевле. G>>Тут никаких идеологических мотивов нет, только экономические.
_>А причём тут какая-то идеология? ) Это только у неадекватов с форумов она встречается, а нормальные люди тупо используют то, что дешевле. ))) И если готовые решения на C++, работающие под Linux оказываются быстрее и дешевле C# аналогов, работающих под виндой, то это и есть решающий фактор.
Именно. Но при этом писать дешевле и удобнее на .NET и запускать свой код под венду.
_>>>Без проблем. ) Но с PostgreSQL ну или чем-то ещё приличным. С кактусами возитесь сами. G>>Ясно, слился. _>Считай как хочешь. )
Так ты хочешь, а не я. Я тебе готов все средства представать, чтобы можно было сравнивать результаты.
_>>>Или Linq не умеет PostgreSQL?) Ну давай тогда возьмём что-нибудь совсем простенькое и популярное, типа sqlite. ))) G>>Все умеет, но никто не будет адаптировать существующие тесты для других движков. Это же не просто поставить постгрес, надо еще базу перенести, текстовые запросы переписать. Никто для тебя этого делать не будет. G>>Или сам, или используй готовую базу на SQL Server. _>Можем не использовать row sql запросы вообще (собственно нас же только сравнение с linq версией интересует). База переноситься в две консольные команды.
А тогда базы для сравнения не будет. Нужен эталонный запрос.
Если есть желание — вперед, переделывай все тесты под postgres.
G>>Но помоему уже все поняли, что доказать свои слова ты не можешь. G>>Можешь не продолжать писать. Большего профана наверное на всем форуме не найдешь. _>Ага, и поэтому ты пишешь мне по 3 сообщения в ответ на одно моё. И поэтому так нервничаешь в каждом из них. Я так и понял. )))
Я пытаюсь созранить баланс здравого смысла, поэтому приходится отвечать на твой бред.
Здравствуйте, alex_public, Вы писали:
_>Давай я тебе напомню ход дискуссии.
_>Всё началось с того, что я высказал тезис о тормознутости ORM на базе Linq. Примеры запросов в которых linq приводит к накладным расходам в 100-500% (в зависимости вида ORM) в теме имеются, так что непонятно какие ещё аргументы нужны. Хотя если кто-то не считает 100-500% накладных расходов существенным, то тут мне уже нечего сказать...
Не 100-500%, а 10-500%. Кроме того,
1 ты игнорируешь результаты сравнения linq2db vs даппер.
2 игнорируешь абсолютные числа замеров
_>Далее, кто-то выдал контртезис, что пусть даже и есть такие накладные расходы, но зато эти ORM производят некие умные (т.е. не просто синтаксис, а как ты сам говорил какая-нибудь там замена join'a и т.п.) оптимизации под конкретную СУБД, которые полностью компенсируют эти расходы. Это естественно не является аргументов в случае сравнения с голыми sql строками (т.к. в них мы просто пишем под конкретную СУБД и естественно оптимально), но является аргументом в случае сравнения с той C++ библиотечкой на шаблонах, которая умеет генерировать код под каждую СУБД, но без всяких оптимизаций. Для подтверждения данного тезиса я попросил привести хотя бы один простейший пример (linq запрос и парочку разных sql запросов, соответствующих ему в разных СУБД). Однако так ни одного и не получил.
Раскрой глаза — всё видео целиком про "(linq запрос и парочку разных sql запросов, соответствующих ему в разных СУБД)"
Ты можешь внятно ответить, чего не хватает в том видео ?
Ты просишь linq запросы и примеры того, что генерируется в результате под каждую БД. Тебе именно это и показали.
Чего не хватает ? Ты в SQL хочешь увидеть чистую магию или чтото навроде ?
I>>Итого — ты или врёшь, или некомпетентен. Вопрос был про то, как подключить _новую_ базу, провайдер и тд.
_>Если надо подключить новую СУБД (в смысле которой раньше вообще не было в проекте), то надо добавить один #include, одну дополнительную ветку в if (который уже скорее всего есть) и пересобрать проект. И в чём проблема? )
Это и есть проблема — необходимость пересобрать проект. Слишком много кастомеров на такой вариант просто не соглашаются. Ну ни как. И слышать об этом не хотят. Причины простые — сайт работает зачастую дольше, чем существует проектная команда.
Если перекомпилировать не надо, то с работой справится один единственный девоп — подложил бинарник, прописал строку подключения и всё. С твоим вариантом надо держать проектную команду или нанимать новую, хотя бы на время.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, gandjustas, Вы писали:
G>>>>Бред. Кэш не становится базой. Сценарии использования разные от слова вообще. C>>>Ещё как становится. G>>Хотя бы обосновать свои слова можешь? А лучше доказать. C>Да очень просто. 100500 сайтов через это прошли — при росте загрузки начинаются: "А что если мы поменяем данные в кэше, вместо того, чтобы их инвалидировать, а то база умирает?"
Кэш не сбрасывается полностью при записи, только небольшой набор ключей.
C>Потом туда добавляется: "Ну так у нас в кэше все данные лежат, давайте мы тут тупой цикл воткнём вместо сложного запроса!" C>Ну и через три-четыре шага оказывается, что кэш становится полноценной БД.
Да-да, это та самая дерьмовая архитектура, которую ты называешь bigdata.
C>>>Правильный кэш всё может. В частности: запросы, в том числе и сложные, гарантию целостности данных (транзакционный лог, репликация с eventual consistency и т.д.). G>>И скорость при этом выше, чем у RDBMS при одинаковом объеме данных? Что за магический движок такой? C>Конечно. Например, Cassandra.
Да, только надежности никакой, 10с таймаут записи на диск. А если подкрутить надёжность, то работает не быстрее рсубд.
G>>Почитай старые посты на coding horror, там много почему SO сделан был именно так. По сути две причины — asp.net mvc и linq2sql. C>И что? А Github вот на Ruby-on-Rails написан. А FaceBook вообще на PHP.
И что? Парни в SO прогадали что ли? Судя по всему нет.
C>>>Если заниматься крупным масштабом, то там просто никак кроме как с Линуксом не получается. Даже у MS, что самое смешное. G>>SO доказывает обратное. Это крупный масштаб. 99% проектов меньший масштаб имеют. C>SO — это примерно средний масштаб. Даже у меня крупнее по количеству запросов в секунду и объёму данных.
Ну покажи свой магический проект, который 10млн запросов в сутки обрабатывает.
Здравствуйте, gandjustas, Вы писали:
G>>>Только в конце 2000-х стало очевидно, что на стандарт уже все положили болт и тогда добавили операторы в T-SQL. _>>Зачем врать то? ) Появилось оно не в конце 2000-ых, а вполне себе в 2012, т.е. через несколько лет после появления в стандарте. И через десятилетие после того, как этим спокойно работали пользователи нормальных СУБД. G>Ты наверное не понимаешь, что для того, чтобы что-то появилось в 2012 это надо было делать в 2008. Спецификации к следующей версии пишутся сильно заранее до релиза.
Ерунду говоришь. Всем известно, что стандарты лишь закрепляют и формализуют давно существующие у лидеров направления решения. И действительно, если говорить о нашем конкретном вопросе, то данной функциональностью (со своим нестандартным синтаксисом) уже многие годы наслаждались пользователи нормальных СУБД. А реализовать через несколько лет после выхода стандарта — это поведение характерное для отстающих.
G>Слушай, ты как маленький. постраничная разбивка результатов никаких проблем никому не приносила с 2008 года. Это толко у тебя с этим были какие-то проблемы. Также как и со скоростью linq впрочем.
С "2008-го года" — как мило. ))) У других такое уже десятилетиями работало. ))) Причём сразу в нормальном варианте (до которого MS дошла только в 2012-ом и только благодаря закреплению этого в стандарте SQL2008).
_>>А вот сейчас похоже можно уже и с SQL Server без linq нормально жить. G> Ты сам начал разговор, с того, что SQL Server — хреновая СУБД и есть гораздо лучше. Вот обоснуй свои слова. Сейчас 2016 год если что. G>15 лет назад все СУБД были говном по сравнению с сегодняшними версиями.
Правильно, я и предлагаю сравнивать решения одного года. Если говорить про прошлое, то там у SQL Server один мрак (в сравнение с конкурирующими продуктами тех же лет!), к которому без linq и подходить то страшно. Сейчас уже похоже стало получше, подтянулись к стандарту...
_>>До тебя так и не дошло? ) Генерируется во время компиляции не сам запрос, а код его создания (склейки строк). Собственно иначе и невозможно, т.к. в запрос входят данные. G>Как до тебя не дошло, что строки могут получиться кардинально разными? G>Берем то же разбиение по страницам. До 2012 SQL Server тебе нужен был подзапрос с row_number, после 2012 подзапрос не нужен. G>Теперь покажи пример кода, который будет сгенерирован, чтобы поддерживать эти кейсы.
Во-первых такое тоже без проблем реализуется на тех же шаблонах. Но естественно в данной конкретной библиотечки ты такого не найдёшь, т.к. она родилась уже после 2013-го и для неё подобные ужасы неактуальны. )))
_>>Помнится в той старой темке ты говорил тоже самое (и даже ещё смешнее, что типа банальных join, groupby и т.п. нет). Но когда тебя ткнули в нос в соответствующие работающие примеры (причём даже не на форуме, а прямо в папке example той библиотечки, в которую ты сам не догадался заглянуть), то по тихому слился из дискуссии. Если сейчас попробовать повторить тоже самое, то не сомневаюсь в аналогичном результате. G>Примеры не были работающими никогда, их невозможно было нигде запустить, чтобы банально проверить качество генерируемого sql. Я тебе и тогда предлагал превратить их в работающие, прогнать на сценариях с проекциями (самыми важными по сути), но ты слился, как и сейчас.
Примеры на гитхабе полностью компилируемые и исполняемые (собственно было бы странно иначе). Я проверял сам и может проверить любой наш читатель. Так что тут ты уже заврался сверх меры, причём на глазах у всех.
_>>А ты даже читать не умеешь похоже. Ответить на фразу "одинаково только если запрос написать полностью аналогичный процедуре, что бредово" фразой "если взять один и тот же запрос, то будет одинаков" может только реальный уникум. G>Тогда потрусь объясни что ты имеешь ввиду? Ты же у нас одаренный а плане SQL, иногда такие перлы выдаешь, что лучше не читать.
Я вроде как вполне ясно написал уже раз десять. Запрос будет существенно отличаться от хранимки и будет оптимальным. При условие что его пишет не альтернативно одарённый человек. Хотя бы потому, что оптимальная запись является короче того страшного запроса в хранимке, с которым ты там боролся.
_>>Вообще то и при использование параметров нормальный запрос будет выглядеть короче твоего чудища в хранимке. И при этом работать оптимизировано. Попробуй сам написать такое и увидишь. Или ты уже совсем разучился с этим своим linq и нужна подсказка? ) G>Я по-разному пробовал, результат не меняется.
Совсем разучился уже со своим Linq. ))) string query="select ... where "+ship_date?"ship_date=@ship_date":"ship_date is null"; Заметно короче и проще твой страшной хранимки, не так ли? ) И при этом полностью оптимально с точки зрения создания планов...
G>6) С точки зрения программы надо клеить строки. Тут два варианта — руками или использовать linq. Руками — чревато ошибками, сложности с рефакторингом и поддержкой.
Это как бы очевидно. Ну в случае C#. ))) И ты буквально повторяешь мои слова в этой теме раньше. Только забываешь добавить, что в обмен на преимущества статической проверки linq привносит оверхед в рантайм. Вопрос что важнее каждый для себя решает сам.
Ну а в некоторых других языка такой дилеммы нет, т.к. там встречается статическая проверка и без оверхеда в рантайме.
G>Так ты хочешь, а не я. Я тебе готов все средства представать, чтобы можно было сравнивать результаты.
Я тебе уже озвучил что мне требуется. ) Пример на C# (для сравнения) работающий с любой вменяемой СУБД (для Linq же это вроде не проблема, не так ли?) С SQL Server я никогда в жизни не встречался и начинать не планирую. )
_>>Можем не использовать row sql запросы вообще (собственно нас же только сравнение с linq версией интересует). База переноситься в две консольные команды. G>А тогда базы для сравнения не будет. Нужен эталонный запрос. G>Если есть желание — вперед, переделывай все тесты под postgres.
Пропорция тормозов linq к голому sql и так понятнa из предыдущего теста. Здесь достаточно linq вариант vs типизированный C++ протестировать.
Здравствуйте, Ikemefula, Вы писали:
_>>Далее, кто-то выдал контртезис, что пусть даже и есть такие накладные расходы, но зато эти ORM производят некие умные (т.е. не просто синтаксис, а как ты сам говорил какая-нибудь там замена join'a и т.п.) оптимизации под конкретную СУБД, которые полностью компенсируют эти расходы. Это естественно не является аргументов в случае сравнения с голыми sql строками (т.к. в них мы просто пишем под конкретную СУБД и естественно оптимально), но является аргументом в случае сравнения с той C++ библиотечкой на шаблонах, которая умеет генерировать код под каждую СУБД, но без всяких оптимизаций. Для подтверждения данного тезиса я попросил привести хотя бы один простейший пример (linq запрос и парочку разных sql запросов, соответствующих ему в разных СУБД). Однако так ни одного и не получил. I>Раскрой глаза — всё видео целиком про "(linq запрос и парочку разных sql запросов, соответствующих ему в разных СУБД)" I>Ты можешь внятно ответить, чего не хватает в том видео ? I>Ты просишь linq запросы и примеры того, что генерируется в результате под каждую БД. Тебе именно это и показали. I>Чего не хватает ? Ты в SQL хочешь увидеть чистую магию или чтото навроде ?
Потому что там нет ни единой оптимизации. Там просто тупо перевод запроса в синтаксис конкретной СУБД (а такое есть везде, в том числе и в обсуждаемой C++ библиотечке).
_>>Если надо подключить новую СУБД (в смысле которой раньше вообще не было в проекте), то надо добавить один #include, одну дополнительную ветку в if (который уже скорее всего есть) и пересобрать проект. И в чём проблема? ) I>Это и есть проблема — необходимость пересобрать проект. Слишком много кастомеров на такой вариант просто не соглашаются. Ну ни как. И слышать об этом не хотят. Причины простые — сайт работает зачастую дольше, чем существует проектная команда. I>Если перекомпилировать не надо, то с работой справится один единственный девоп — подложил бинарник, прописал строку подключения и всё. С твоим вариантом надо держать проектную команду или нанимать новую, хотя бы на время.
Ну так значит добавь изначально все известные провайдеры и всё. Их же реально используемых всего несколько штук и новые что-то не особо плодятся. )
Здравствуйте, alex_public, Вы писали:
G>>Слушай, ты как маленький. постраничная разбивка результатов никаких проблем никому не приносила с 2008 года. Это толко у тебя с этим были какие-то проблемы. Также как и со скоростью linq впрочем. _>С "2008-го года" — как мило. ))) У других такое уже десятилетиями работало. ))) Причём сразу в нормальном варианте (до которого MS дошла только в 2012-ом и только благодаря закреплению этого в стандарте SQL2008).
Тут всё чуть сложнее. Функциональность limit и offset, с точки зрения реляционного исчисления, это исключительный бред, особенно offset. Это не моя точка зрения, но я несколько раз слышал таких теоретиков-пуристов.
Возьми типичный форум (RSDN тоже подходит). Запрос вида http:// rsdn.ru/Forum/MsgUList.aspx?uid=${uid}&start=1001 для показа следующих K сообщений — это типичный алгоритм Шлемиэля за счёт преобразование в что-то вида select поля from messages where uid=${uid} order by msgid desc limit $n_per_page offset $offset (не знаю, как именно сделано на RSDN, но в куче доступных форумных движков только так); каждый следующий запрос дороже, и только качественный индекс позволяет сохранять скорость работы приемлемой. Можно было бы сделать вместо этого получение номера самого раннего из показанных на странице сообщений, формировать по нему URL (типа ...uid=25668&before=4195716), и в запросе тогда вместо offset $K будет where ... and messages.msg_id < $start_msg_id. Но я очень мало где видел такую реализацию — только два случая — blogspot и facebook; сразу видно, кто озабочен проблемой нагрузки, а кому пофиг Некоторые умудряются даже "оптимизировать" такие запросы через вложенный select с предварительной выборкой только id, а потом по списку id брать уже тела сообщений, join'ить и прочие тяжёлые запросы; можешь поискать такие рекомендации на StackOverflow пример пример 2
Второй аргумент, выдвигаемый такими теоретиками — это возможное дублирование или пропуск строк, если выборка с limit+offset делается по неуникальному индексу. Пусть есть объекты A,B,C с параметром X=12,8,8 соответственно. Выборка с "order by X desc limit 2" может дать A,B, а может A,C; limit 2 offset 2 — или C, или B; и что именно когда выберется — зависит от фазы Луны. Поэтому стандартный ответ этих теоретиков — "вы хотите неправильного, пользуйтесь курсорами". То, что есть масса случаев правильного разумного использования этой фичи, хотя бы при уникальном индексе, их не волнует.
В любом подобном комитете адская смесь из теоретиков, практиков и при этом сторонников разных подходов и апологетов вендоров, поэтому любое решение имеет колоссальные шансы превратиться в "верблюд — лошадь, разработанная комитетом". То, что limit+offset не были введены в SQL с самого начала, показывает огромное влияние теоретиков-пуристов. В таком случае, если жизнь продавила против их желания фичу, которой они не хотят, они должны были её максимально испортить — чтобы практикам "жизнь мёдом не казалась". Поэтому они и были введены в стандарт с предельно идиотским и многословным синтаксисом. Опять-таки, у меня точных данных нет — это нужна инсайдерская информация, в публичных документах комитета этого нет — но к этому выводу ведёт вся обычная административная логика.
Если кто-то имеет точные данные против такого вывода — милости просим в студию.
G>>Берем то же разбиение по страницам. До 2012 SQL Server тебе нужен был подзапрос с row_number, после 2012 подзапрос не нужен.
У Oracle тоже очень долго обеспечивать limit можно было только через rownum, причём были стандартные грабли, о которых всех предупреждали. Offset можно было делать только на стороне клиента.
Здравствуйте, alex_public, Вы писали:
_>Зачем врать то? ) Появилось оно не в конце 2000-ых, а вполне себе в 2012, т.е. через несколько лет после появления в стандарте. И через десятилетие после того, как этим спокойно работали пользователи нормальных СУБД.
Судя по всему, под "нормальными" СУБД вы имеете в виду MySQL. Это в очередной раз показывает, что рассуждать на эту тему вам рановато.
Но это неважно, потому что мы живём не в мире "нормальных" СУБД, а в реальном мире. Где нет единой СУБД на все случаи жизни, где диалекты отличаются, и даже качество поддержки одного и того же ANSI SQL существенно различно. Тот же MySQL, который вам так нравится за лояльный синтаксис, имел в те давние годы привычку тупо падать на мало-мальски сложных подзапросах.
Вот например:http://stackoverflow.com/questions/2298497/mysql-left-join-subquery-fail
Кроме того, над его оптимизатором не смеялся только ленивый: http://www.xaprb.com/blog/2006/04/30/how-to-optimize-subqueries-and-joins-in-mysql/
Это означает, что приложению лучше бы приготовиться к тому, что надо оптимизировать запросы самостоятельно. И для тех СУБД, которые лучше работают с subquery, использовать subquery, а для тех, кто хорошо оптимизирует join, использовать join. И вот linq предлагает такой способ. А sqlpp — это всего лишь низкоуровневая проверялка синтаксиса для SQL в C++.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Всем известно, что стандарты лишь закрепляют и формализуют давно существующие у лидеров направления решения. И действительно, если говорить о нашем конкретном вопросе, то данной функциональностью (со своим нестандартным синтаксисом) уже многие годы наслаждались пользователи нормальных СУБД. А реализовать через несколько лет после выхода стандарта — это поведение характерное для отстающих.
И че?
G>>Слушай, ты как маленький. постраничная разбивка результатов никаких проблем никому не приносила с 2008 года. Это толко у тебя с этим были какие-то проблемы. Также как и со скоростью linq впрочем. _>С "2008-го года" — как мило. ))) У других такое уже десятилетиями работало. ))) Причём сразу в нормальном варианте (до которого MS дошла только в 2012-ом и только благодаря закреплению этого в стандарте SQL2008).
И че?
_>>>А вот сейчас похоже можно уже и с SQL Server без linq нормально жить. G>> Ты сам начал разговор, с того, что SQL Server — хреновая СУБД и есть гораздо лучше. Вот обоснуй свои слова. Сейчас 2016 год если что. G>>15 лет назад все СУБД были говном по сравнению с сегодняшними версиями.
_>Правильно, я и предлагаю сравнивать решения одного года. Если говорить про прошлое, то там у SQL Server один мрак (в сравнение с конкурирующими продуктами тех же лет!), к которому без linq и подходить то страшно. Сейчас уже похоже стало получше, подтянулись к стандарту...
Давай сравнивать решения 2016 года.
_>>>До тебя так и не дошло? ) Генерируется во время компиляции не сам запрос, а код его создания (склейки строк). Собственно иначе и невозможно, т.к. в запрос входят данные. G>>Как до тебя не дошло, что строки могут получиться кардинально разными? G>>Берем то же разбиение по страницам. До 2012 SQL Server тебе нужен был подзапрос с row_number, после 2012 подзапрос не нужен. G>>Теперь покажи пример кода, который будет сгенерирован, чтобы поддерживать эти кейсы. _>Во-первых такое тоже без проблем реализуется на тех же шаблонах. Но естественно в данной конкретной библиотечки ты такого не найдёшь, т.к. она родилась уже после 2013-го и для неё подобные ужасы неактуальны. )))
Если "без проблем", то почему "не найдешь" ? Авторы не хотят поддерживать больше движков? Или все таки не могут?
Ты сам себе противоречишь.
_>Примеры на гитхабе полностью компилируемые и исполняемые (собственно было бы странно иначе). Я проверял сам и может проверить любой наш читатель. Так что тут ты уже заврался сверх меры, причём на глазах у всех.
Ты предлагаешь тебе на слово поверить? Сделай тесты на этой библиотеке, докажи что не свистишь, заодно и проверим быстродействие.
_>>>А ты даже читать не умеешь похоже. Ответить на фразу "одинаково только если запрос написать полностью аналогичный процедуре, что бредово" фразой "если взять один и тот же запрос, то будет одинаков" может только реальный уникум. G>>Тогда потрусь объясни что ты имеешь ввиду? Ты же у нас одаренный а плане SQL, иногда такие перлы выдаешь, что лучше не читать. _>Я вроде как вполне ясно написал уже раз десять. Запрос будет существенно отличаться от хранимки и будет оптимальным. При условие что его пишет не альтернативно одарённый человек. Хотя бы потому, что оптимальная запись является короче того страшного запроса в хранимке, с которым ты там боролся.
Ну так напиши этот оптимальный запрос.
_>>>Вообще то и при использование параметров нормальный запрос будет выглядеть короче твоего чудища в хранимке. И при этом работать оптимизировано. Попробуй сам написать такое и увидишь. Или ты уже совсем разучился с этим своим linq и нужна подсказка? ) G>>Я по-разному пробовал, результат не меняется. _>Совсем разучился уже со своим Linq. ))) string query="select ... where "+ship_date?"ship_date=@ship_date":"ship_date is null"; Заметно короче и проще твой страшной хранимки, не так ли? ) И при этом полностью оптимально с точки зрения создания планов...
Наконец-то, через 5 постов ты родил строку кода.
Надеюсь ты понял какую проблему надо решать.
Теперь от параметра не просто добавляется фильтр, а еще и делается джоин. Без параметров никаких джоинов нет.
Сама коллекция product может содержать быть отфильтрована и другими предикатами до фильтра по имени категории.
Как это сделать на склейке строк или твоей библиотеке?
Как родишь код, подумай что таких параметров на каждый запрос будет десяток.
G>>6) С точки зрения программы надо клеить строки. Тут два варианта — руками или использовать linq. Руками — чревато ошибками, сложности с рефакторингом и поддержкой. _>Это как бы очевидно. Ну в случае C#. ))) И ты буквально повторяешь мои слова в этой теме раньше. Только забываешь добавить, что в обмен на преимущества статической проверки linq привносит оверхед в рантайм. Вопрос что важнее каждый для себя решает сам.
Да-да, только раньше ты не понимал какую проблему решает linq, но почитал про планы запросов, кеширование и psp, и наконец разобрался, молодец.
Но ты понял только половину проблемы — генерация оптимальных запросов. А вторая половина проблемы — затраты трудочасов на такую генерацию.
Выше для тебя пример, чтобы ты попробовал его изобразить с помощью склейки строк.
_>Ну а в некоторых других языка такой дилеммы нет, т.к. там встречается статическая проверка и без оверхеда в рантайме.
Вот тебе пример выше — покажи как статическая проверка в нем сработает.
G>>Так ты хочешь, а не я. Я тебе готов все средства представать, чтобы можно было сравнивать результаты. _>Я тебе уже озвучил что мне требуется. ) Пример на C# (для сравнения) работающий с любой вменяемой СУБД (для Linq же это вроде не проблема, не так ли?) С SQL Server я никогда в жизни не встречался и начинать не планирую. )
Ты сейчас вертишься как уж на сковородке чтобы избежать прямого сравнения говноподелки с linq любыми способами.
Давай так:
1) ты вроде утверждал, что можно с помощью конфига подменить генерацию запросов в коде на C++, чтобы они работали для другой базы
2) Ты утверждал, что базу SQL Server можно быстро перегнать в posrtges
3) Ты говорил что выложишь исходники
То есть ты можешь взять базу northwind, перегать её в postgres, написать для нее тестовые запросы, выложить код на github.
А мы просто с гитхаба возьмем код, поменяем параметры чтобы тоже самое работало с SQL Server.
Так?
И ты работаешь с чем хочешь и сравнить потом можно. Так что приступай.
Здравствуйте, alex_public, Вы писали:
I>>Ты просишь linq запросы и примеры того, что генерируется в результате под каждую БД. Тебе именно это и показали. I>>Чего не хватает ? Ты в SQL хочешь увидеть чистую магию или чтото навроде ?
_>Потому что там нет ни единой оптимизации. Там просто тупо перевод запроса в синтаксис конкретной СУБД (а такое есть везде, в том числе и в обсуждаемой C++ библиотечке).
Разумеется, это не так. Ты невнимательно смотрел видео. Например, на 16й минуте видна разница в структуре запросов. Это именно то, о чем тебе и говорили.
Реально запрос будет меняться в зависимости от того, какую базу подключишь, mssql древний или самый свежий.
I>>Если перекомпилировать не надо, то с работой справится один единственный девоп — подложил бинарник, прописал строку подключения и всё. С твоим вариантом надо держать проектную команду или нанимать новую, хотя бы на время.
_>Ну так значит добавь изначально все известные провайдеры и всё. Их же реально используемых всего несколько штук и новые что-то не особо плодятся. )
А откуда твоё чудо узнает о новшествах в новой версии mssql, db2, oracle и тд ? Неужели новый движок базы будет мучить старыми(и медленными) запросами ?
Здравствуйте, gandjustas, Вы писали:
G>Поэтому в T-SQL долго не включали операторы постраничного разбиения. А вот ranking functions как раз в стандарте есть и через них прекрасно делается разбиение на страницы.
Прошу пару уточнений
1) ranking function это то же, что window function стандарта и других серверов,
или есть отличия?
2) какой именно способ подразумевается под "прекрасно" — select по вложенному подзапросу с row_number(), или что-то другое?
G>Только в конце 2000-х стало очевидно, что на стандарт уже все положили болт и тогда добавили операторы в T-SQL.
Ну, что они таки добавили это в стандарт, ты уже в курсе. С намеренно громоздким синтаксисом, но без запрета использовать это без упорядочения (MS допускает только с упорядочением, что слегка чрезмерно).
G>Ты хочешь сказать, что надо подставлять параметр в текст запроса, а не использовать механизм параметров? G>Ты опять показал свой профанизм. G>Подстановка параметров имеет два огроменных недостатка: G>1) SQL-инъекции в случае текстовых параметров, они гарантированно будут. Надежного метода экранирования практически нет.
Хммм
Нет даже для конкретного движка в конкретном режиме? (ansi on/off)
("Меня гложут смутные сомнения...")
Нет для конкретного движка, если не знать режим соединения?
Нет в общем случае (известен конкретный движок с проблемами)?
Здравствуйте, netch80, Вы писали:
N>2) какой именно способ подразумевается под "прекрасно" — select по вложенному подзапросу с row_number(), или что-то другое?
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, netch80, Вы писали:
N>>2) какой именно способ подразумевается под "прекрасно" — select по вложенному подзапросу с row_number(), или что-то другое?
S>http://rsdn.ru/forum/dotnet/6162906
Это всё совсем не о том, если я правильно прочитал всю ветку. Вот вы читаете список чьих-то сообщений и выходите на не-первую страницу. Запрос выводимых сообщений это что-то вроде ответа на select * from messages where user_id=12345 order by msg_id desc limit 50 offset 100. Какая замена применялась лучше всего в MS SQL до введения поддержки offset и fetch first из новых SQL? Я предполагаю, что это что-то вроде select * from (select row_number() over(...), остальные поля, условия) where row_number between 100 and 149, но я с MS SQL такого никогда не пробовал, вопрос был в точном проверенном методе.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, netch80, Вы писали:
N>>>2) какой именно способ подразумевается под "прекрасно" — select по вложенному подзапросу с row_number(), или что-то другое?
S>>http://rsdn.ru/forum/dotnet/6162906
N>Это всё совсем не о том, если я правильно прочитал всю ветку. Вот вы читаете список чьих-то сообщений и выходите на не-первую страницу. Запрос выводимых сообщений это что-то вроде ответа на select * from messages where user_id=12345 order by msg_id desc limit 50 offset 100. Какая замена применялась лучше всего в MS SQL до введения поддержки offset и fetch first из новых SQL? Я предполагаю, что это что-то вроде select * from (select row_number() over(...), остальные поля, условия) where row_number between 100 and 149, но я с MS SQL такого никогда не пробовал, вопрос был в точном проверенном методе.
Ну почему же.
select top 1 with ties d1.SalesOrderID, d1.OrderQty
from Sales.SalesOrderDetail d1
order by row_number() over(partition by d1.SalesOrderID order by d1.OrderQty desc)
В следующем примере показан расчет номеров всех строк в таблице SalesOrderHeader в порядке OrderDate с последующим возвращением строк с номерами от 50 до 60 включительно.
USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>WITH OrderedOrders AS S>( S> SELECT SalesOrderID, OrderDate, S> ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber S> FROM Sales.SalesOrderHeader S>) S>SELECT SalesOrderID, OrderDate, RowNumber S>FROM OrderedOrders S>WHERE RowNumber BETWEEN 50 AND 60; S>[/sql]
А, то есть тут угадал, кроме места выполнения вложенного запроса (WITH). Спасибо, понятно.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, gandjustas, Вы писали:
G>>Поэтому в T-SQL долго не включали операторы постраничного разбиения. А вот ranking functions как раз в стандарте есть и через них прекрасно делается разбиение на страницы.
N>Прошу пару уточнений N>1) ranking function это то же, что window function стандарта и других серверов, N>или есть отличия?
Наверное те же
N>2) какой именно способ подразумевается под "прекрасно" — select по вложенному подзапросу с row_number(), или что-то другое?
Да.
G>>Только в конце 2000-х стало очевидно, что на стандарт уже все положили болт и тогда добавили операторы в T-SQL. N>Ну, что они таки добавили это в стандарт, ты уже в курсе. С намеренно громоздким синтаксисом, но без запрета использовать это без упорядочения (MS допускает только с упорядочением, что слегка чрезмерно).
Это случилось уже после того как я перестал следить за развитием событий.
G>>Ты хочешь сказать, что надо подставлять параметр в текст запроса, а не использовать механизм параметров? G>>Ты опять показал свой профанизм. G>>Подстановка параметров имеет два огроменных недостатка: G>>1) SQL-инъекции в случае текстовых параметров, они гарантированно будут. Надежного метода экранирования практически нет.
N>Хммм N>Нет даже для конкретного движка в конкретном режиме? (ansi on/off)
Мой хороший знакомый показывал как для mysql, sql server и postgres обходил все типовые способы экранирования строк.
Он пентестингом занимается. Про все 100% не уверен, но он утверждает, что может поломать при практически любой конфигурации.
Может преувеличивает.
В любом случае я бы не стал рассчитывать, что обычный разработчик напишет экранирование корректно.
Здравствуйте, gandjustas, Вы писали:
N>>1) ranking function это то же, что window function стандарта и других серверов, N>>или есть отличия? G>Наверное те же N>>2) какой именно способ подразумевается под "прекрасно" — select по вложенному подзапросу с row_number(), или что-то другое? G>Да.
Ясно, спасибо.
G>>>1) SQL-инъекции в случае текстовых параметров, они гарантированно будут. Надежного метода экранирования практически нет. N>>Хммм N>>Нет даже для конкретного движка в конкретном режиме? (ansi on/off) G>Мой хороший знакомый показывал как для mysql, sql server и postgres обходил все типовые способы экранирования строк.
Видимо, всякими символами вроде \x00, не иначе. Там, да, надо чуть аккуратнее писать, чем рядовой PHPер сделает.
Хотя в библиотеках уже всё давно должны были вылизать.
G>Он пентестингом занимается. Про все 100% не уверен, но он утверждает, что может поломать при практически любой конфигурации. G>Может преувеличивает. G>В любом случае я бы не стал рассчитывать, что обычный разработчик напишет экранирование корректно.
Статистически — может, и правду говорит — если ему приносят на разбор по два новых CRM движка на PHP в неделю
Вообще же это больше похоже на ошибки движков.
У них есть своя специфика, но, насколько я понял доступные тексты стандартов, алгоритм вида "все апострофы удвоить и вокруг результата нарисовать по одному апострофу; поставить впереди N или U&, если надо" обязан сработать чуть более чем всегда.
Поэтому у "обычного разработчика" не должно быть проблем, если он вообще не забыл сделать экранирование.
Здравствуйте, Sinclair, Вы писали:
_>>Зачем врать то? ) Появилось оно не в конце 2000-ых, а вполне себе в 2012, т.е. через несколько лет после появления в стандарте. И через десятилетие после того, как этим спокойно работали пользователи нормальных СУБД. S>Судя по всему, под "нормальными" СУБД вы имеете в виду MySQL. Это в очередной раз показывает, что рассуждать на эту тему вам рановато.
Почему обязательно MySQL? ) Там и PostgreSQL и ещё куча менее известных РСУБД.
S>Но это неважно, потому что мы живём не в мире "нормальных" СУБД, а в реальном мире. Где нет единой СУБД на все случаи жизни, где диалекты отличаются, и даже качество поддержки одного и того же ANSI SQL существенно различно. Тот же MySQL, который вам так нравится за лояльный синтаксис, имел в те давние годы привычку тупо падать на мало-мальски сложных подзапросах. S>Вот например:http://stackoverflow.com/questions/2298497/mysql-left-join-subquery-fail S>Кроме того, над его оптимизатором не смеялся только ленивый: http://www.xaprb.com/blog/2006/04/30/how-to-optimize-subqueries-and-joins-in-mysql/
Кстати, насчёт быстродействия mysql не всё так однозначно, т.к. на простых запросах она при этом же существенно обходила другие СУБД. ) Недаром фейсбук построил на их базе своё подобие nosql. )))
S>Это означает, что приложению лучше бы приготовиться к тому, что надо оптимизировать запросы самостоятельно. И для тех СУБД, которые лучше работают с subquery, использовать subquery, а для тех, кто хорошо оптимизирует join, использовать join. И вот linq предлагает такой способ. А sqlpp — это всего лишь низкоуровневая проверялка синтаксиса для SQL в C++.
Насчёт sqlpp сказано всё верно. А вот насчёт Linq я вижу новое повторение того же мифа, который тут уже неоднократно озвучивали, но при этом не смогли привести ни единого (!) примера для подтверждения.