Здравствуйте, _ABC_, Вы писали:
I>>У меня нет под рукой точных запросов. Все три выдают один и тот же результат, разница только в быстродействии. _AB>Если диалект SQL реализует ANSI-совместимый COUNT, то второй вариант вернет число всех записей из набора данных (таблицы), _AB>а первый только те, у которых x is not null.
x это не колумн, а таблица, чтото навроде. нулей нигде нет.
Здравствуйте, Sinclair, Вы писали:
_>>Я — могу. Так же как и любой, знакомый с языком SQL. ))) Ну а для неосиливших SQL действительно стоит поискать другие инструменты. ) S> S>Речь идёт не о том, что кто-то конкретный врукопашную неспособен соптимизировать SQL. S>А о том, что можно декомпозировать задачу. В одном месте — определить функцию типа getAllOrders, которая возвращает все заказы, видимые текущему пользователю (...where acl.UserID = @currentUser), а в других местах (нескольких) ей пользоваться. S>При этом в одном месте будут выводиться все детали ордера, а в другом — только подсчитываться общее количество. S>И в результирующем sql не будет ничего лишнего — никаких join, не участвующих в выборке, никаких полей, не попавших в финальную проекцию. S>В плохом случае вообще эти части проекта компилируются раздельно — потому что их пишут разные команды. S>И никто вам не даст возможности руками выполнить инлайнинг и подпатчить SQL. S>В совсем плохом случае возможность дадут, а вот денег на то, чтобы руками выписать оптимальный SQL для всех 128 вариантов сочетаний — не дадут. И неосилившим linq придётся поискать другую работу.
Проект с подобной архитектурой обречён быть тормозом. Соответственно это означает одно их двух: или для проекта быстродействие не критично или же изначальный архитектор проекта был некомпетентен.
Здравствуйте, Sinclair, Вы писали:
_>>Что-то ты бредишь) Библиотеки в любом случае компилируются где-то, один раз. А линкуются динамически или статически — это уже по вкусу разработчиков. Мне больше нравится статическое решение, т.к. с ним меньше проблем при распространение. S>А ещё все твои мета-трюки с превращением linq-запроса в склейку строк на C++ возможны только при подстановке исходников-в-исходники. S>Если один драйвер хочет заменять .take(1000) на "top 1000", а другой — на "limit 0, 1000", то для "склейки строк" придётся эти драйвера описывать в виде шаблонов, поставлять в исходниках, и компилировать статически.
Да, именно так оно и работает. Только вот ты видимо путаешь терминологию. На шаблонах надо делать соответствующие провайдеры (в терминологии Linq, в sqlpp11 они называются Database Connector) — тонкую прослойку между библиотекой и драйвером СУБД, и это как раз сделано. А драйверы СУБД (которые предоставляются их производителями в виде соответствующих SDK) естественно переделывать на шаблоны не надо. )))
S>А если захочется как в С# — подменять драйвер в уже скомпилированном и развёрнутом приложении ппри помощи строки в конфиге — то придётся отказаться от шаблонов и склейки строк, а заниматься полноценным анализом expression trees в рантайме. Со сравнимой, ессно, производительностью.
Эм, а зачем подменять эту тонкую прослойку в развёрнутом приложение? )
Здравствуйте, Ikemefula, Вы писали:
_>>Заканчивай с теорией и переходи к конкретным реальным примерам. Хотя бы к одному. ) I>Вот, из последнего, с чем столкнулся. Каждая из трех строчек лидирует по производительности в зависимости от базы I>
I>select count(x) from ... таблица
I>select count(1) from ... 1 или *
I>select count(id) from ... праймари кей
I>
I>Если твоя мулька генерит разных код в зависимости от базы, все в порядке, она умеет оптимизировать. А если нет, то запрос придется переписывать под разные базы.
Даже если забыть о том, что это не совсем одинаковые запросы... Ты в начале покажи мне соответствующий linq код, из которого данные запросы генерируются для разных СУБД (и перечисли их с указанием какой sql для какой СУБД генерируется).
Здравствуйте, Serginio1, Вы писали:
S>>>>> Хранимые процедуры можно применять и в Linq, в том числе на CLR _>>>>Можно. ) Но не нужно (см. пример тех же SO). S>>> А где написано, что ХП не используют CLR (.Net)? _>>Перечитай внимательно цитату в этом http://rsdn.ru/forum/flame.comp/6412784.1
Здравствуйте, gandjustas, Вы писали:
G>У меня стойкое ощущение дежа-вю. G>Ты все тоже самое говорил год назад, и два года назад, может и три года назад, но я уже не помню.
Так и есть. Фанаты linq что тогда были неадекватные, что сейчас. В ответ на высказанный мимоходом очевидный тезис о тормознутости данного инструмента они начинают длинные и бесплодные дискуссии. Единственное отличие этой дискуссии от прошлой в том, что в той из реальных оценок присутствовали только слова пары человека (в том числе тебя) с форума. А в этот раз тут можно найти гораздо более интересные замеры (опять же не мои), типа таких http://liiw.blogspot.ru/2015/03/performance-of-linq-to-db-vs-entity.html. Или же вот такие https://nickcraver.com/blog/2016/02/17/stack-overflow-the-architecture-2016-edition/ любопытные данные (это уже я нашёл) о том что применяют реальные профи из мира .net.
G>Давай по порядку: G>Про быстродействие Linq G>https://youtu.be/I2cNUUC3tiI?t=29m59s G>Смотри внимательно на результаты.
Смотрю внимательно. ) Тесты в видео выглядят не особо профессионально (нет различий ни по сложности запроса, ни по результату). Но при этом дают похожие (см. первую ссылку выше) результаты. Довольно печальные для Linq. Правда в видео ты это очень забавно попытался обойти))) Фраза типа "всего лишь 12 мс накладных расходов — ерунда" конечно выглядит прилично... А вот если мы переозвучим её как "всего лишь 110% накладных расходов — ерунда", то она тоже будет звучать прилично? )))
G>Тормоза Linq существуют в очень высоконагруженных системах, и в головах некоторых людей.
Если ты посмотришь внимательно, то именно это (ну без добавки про головы некоторых людей) я и говорил в данной темке, причём неоднократно. Очевидно, что для всяких слабонагруженных систем linq отлично подходит. Могу показать тебе ссылки на эти сообщения, если сам не увидел. )
G>Причем в нагруженных системах легко эти тормоза обойти за счет компиляции запросов, а в головах людей эта проблема нерешаемая.
Ха, а вот тут уже совсем другой расклад появляется — здесь удобство становится даже похуже голых sql строк. Я уже не говорю об инструментах из других языков, в которых есть возможность иметь полностью удобный вид без малейших накладных расходов.
Здравствуйте, alex_public, Вы писали:
_>Проект с подобной архитектурой обречён быть тормозом.
.
Это проект со склейкой SQL строк обречён быть тормозом. Вы про производительность приложений с DBMS лучше не пишите ничего. Не так стыдно потом будет перечитывать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали: _>Эм, а зачем подменять эту тонкую прослойку в развёрнутом приложение? )
Ну вот например несколько экземпляров нашего развёрнутого приложения с год назад было решено перевести с SQLite на MS SQL — потому что используемые объёмы выросли, а SQLite, как ни крути, непригоден для промышленного использования. Это вполне себе валидный бизнес-сценарий.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
S>>>>>> Хранимые процедуры можно применять и в Linq, в том числе на CLR _>>>>>Можно. ) Но не нужно (см. пример тех же SO). S>>>> А где написано, что ХП не используют CLR (.Net)? _>>>Перечитай внимательно цитату в этом http://rsdn.ru/forum/flame.comp/6412784.1
Stack Overflow has only 1 stored procedure in the database and I intend to move that last vestige into code.
Я плохо знаю англицкий. Переведи
We write almost every query (as you would using Stored Procedures), they simply live in code — not hidden in a stored procedure. Also keep in mind that we manage hundreds of copies of the same schema across hundreds of databases (one per site). The pain points I mention above are multiplied in our situation.
I don't think EF/L2S generated code is any better than stored procedures, my personal feelings are that they're both bad for different reasons *for us*. Dapper and raw SQL let's us tune queries the way we want, manage them trivially (all in git, since they're just part of the code), and get all of the wins that stored procedures allow us without the downsides (as I see them) of the abstraction.
Я так понимаю, что они используют пакетные запросы. Но в них можно использовать и CLR
Опять же
Our usage of SQL is pretty simple. Simple is fast. Though some queries can be crazy, our interaction with SQL itself is fairly vanilla. We have some legacy Linq2Sql, but all new development is using Dapper, our open source Micro-ORM using POCOs. Let me put this another way: Stack Overflow has only 1 stored procedure in the database and I intend to move that last vestige into code.
important note Dapper assumes your Id columns are named "Id" or "id", if your primary key is different or you would like to split the wide row at point other than "Id", use the optional 'splitOn' parameter.
Multiple Results
Dapper allows you to process multiple result grids in a single query.
Example:
var sql =
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";
using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
var returns = multi.Read<Return>().ToList();
...
}
Stored Procedures
Dapper fully supports stored procs:
var user = cnn.Query<User>("spGetUser", new {Id = 1},
commandType: CommandType.StoredProcedure).SingleOrDefault();
If you want something more fancy, you can do:
var p = new DynamicParameters();
p.Add("@a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
S>>>>>> Хранимые процедуры можно применять и в Linq, в том числе на CLR _>>>>>Можно. ) Но не нужно (см. пример тех же SO). S>>>> А где написано, что ХП не используют CLR (.Net)? _>>>Перечитай внимательно цитату в этом http://rsdn.ru/forum/flame.comp/6412784.1
Вот тебе типизированные запросы о которых ты мечтал. При этом быстрые.
Performance of SELECT mapping over 500 iterations — POCO serialization
Method
Duration
Remarks
Hand coded (using a SqlDataReader ) 47ms Can be faster
Dapper ExecuteMapperQuery 49ms
ServiceStack.OrmLite (QueryById) 50ms
PetaPoco 52ms
BLToolkit 80ms
SubSonic CodingHorror 107ms
NHibernate SQL 104ms
Linq 2 SQL ExecuteQuery 181ms
Entity framework ExecuteStoreQuery 631ms
Еще раз Linq нужен для скорости программирования, на сложном коде, с выводом типа, работа с анонимными классами, динамическое построение запроса итд. Пример 1С я тебе уже тысячу раз приводил, где типизацией и не пахнет. А что касается скорости и типизации можно использовать Dapper
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
_>Ха, а вот тут уже совсем другой расклад появляется — здесь удобство становится даже похуже голых sql строк. Я уже не говорю об инструментах из других языков, в которых есть возможность иметь полностью удобный вид без малейших накладных расходов.
Послушайте. Вы на банальнейших, примитивнейших примерах умудрились вляпаться в sql injection и в приведение якобы ANSI-совместимого
SQL запроса с синтаксической ошибкой. Я кроме этих двух примеров ничего от Вас не нашел больше в плане SQL.
Linq несет определенные накладные расходы, никто не спорит. При действительно серьезной нагрузке это может стать узким местом. Но при этом
он обычно (подчеркну — обычно) генерирует код, который оптимальнее того, что написал бы (или склеил) среднестатистический разработчик, который
полагает, что знает SQL. К тому же, он это делает безопасно и корректно. Вы не справились в приведенных Вами примерах даже со вторым. Про первое
говорить пока что рано, хотя и там потенциально все печально, т.к. озвученный принцип построен на подзапросах и из запроса тащатся лишние данные,
что обойдется в потенциале существенно дороже обхода дерева выражений.
Здравствуйте, alex_public, Вы писали:
I>>Относительно чего тормозят, mov ax, bx ?
_>Уже раз 100 говорилось — относительно прямого доступа к БД.
То есть, относительно голых запросов без какого либо кеширования. Правильно ?
А с кешированием как быть ?
I>>У тебя замеры чисто синтетические, без учета реального кеширования и тд.
_>Зато не синтические и с беспредельным кешированием на Stack Overflow, но что-то выводы одинаковые... )))
Даппер они начали использовать еще в незапамятные времена. Кроме того, им вообще не нужны никакие возможности от ORM. Им, по большому счет, им ORM не нужен.
Здравствуйте, _ABC_, Вы писали: _AB>Linq несет определенные накладные расходы, никто не спорит. При действительно серьезной нагрузке это может стать узким местом. Но при этом _AB>он обычно (подчеркну — обычно) генерирует код, который оптимальнее того, что написал бы (или склеил) среднестатистический разработчик, который _AB>полагает, что знает SQL. К тому же, он это делает безопасно и корректно. Вы не справились в приведенных Вами примерах даже со вторым. Про первое _AB>говорить пока что рано, хотя и там потенциально все печально, т.к. озвученный принцип построен на подзапросах и из запроса тащатся лишние данные, _AB>что обойдется в потенциале существенно дороже обхода дерева выражений.
Более того, обычно оптимизатор на стороне DBMS достаточно консервативен. Он не занимается глобальными семантическими оптимизациями типа выброса незначащих джойнов или приведения подзапросов.
Поэтому подготовка хорошего SQL — это the must для приложения, претендующего на производительность. Говноинструменты могут сколько угодно гордиться тем, что у них тратится на 960 меньше тактов для генерации SQL строки.
А сервер от лишнего mytable t1 join mytable t2 on t1.id = t2.id поднимет с винта лишний терабайт данных. И на синтетике, возвращающей 0 строк, говноинструмент покажет выигрыш, а с реальными данными тупо ляжет навзничь.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Ikemefula, Вы писали:
_>>>Кстати, если глянуть страничку этой библиотеки (https://github.com/StackExchange/dapper-dot-net), то можно увидеть много любопытных замеров быстродействия. Из которых сразу понятна ориентация этой библиотечки и что там думают про linq1sql и т.п. ))) I>>Недавно мы обсуждали замеры производительности. Ты не забыл ? Так вот фокус в том, что linq2db работает быстрее чем dapper.
_>Это где ты такое взял? )
I>>Но вообще, dapper это сильно специфичный инструмент, микро-ОРМ. Вот http://www.mindscapehq.com/blog/index.php/2011/12/05/5-reasons-not-to-use-a-micro-orm/
Ormbattle я реанимировал. Если честно, перформанс тесты там не на надлежащем уровне, времени у меня на это нет. Больше интересовала зрелость linq в библиотеках.
Здравствуйте, alex_public, Вы писали:
_>Даже если забыть о том, что это не совсем одинаковые запросы... Ты в начале покажи мне соответствующий linq код, из которого данные запросы генерируются для разных СУБД (и перечисли их с указанием какой sql для какой СУБД генерируется).
Ну делать нам тут не...
Вот посмотри видео, где Игорь показывает как генерятся разные CRUD запросы для разных баз данных. Занимательная штука. Или просто послушай музычку и расслабся )
_AB>Linq несет определенные накладные расходы, никто не спорит. При действительно серьезной нагрузке это может стать узким местом. Но при этом _AB>он обычно (подчеркну — обычно) генерирует код, который оптимальнее того, что написал бы (или склеил) среднестатистический разработчик, который _AB>полагает, что знает SQL. К тому же, он это делает безопасно и корректно. Вы не справились в приведенных Вами примерах даже со вторым. Про первое _AB>говорить пока что рано, хотя и там потенциально все печально, т.к. озвученный принцип построен на подзапросах и из запроса тащатся лишние данные, _AB>что обойдется в потенциале существенно дороже обхода дерева выражений.
Особенно когда таких запросов могут быть тысячи. Помню писал упрощенку, так там для определения оплаченных партий поставщику и покупателями и прочие выкрутоны приходилось делать алгоритм на 10 000 строк.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>У меня стойкое ощущение дежа-вю. G>>Ты все тоже самое говорил год назад, и два года назад, может и три года назад, но я уже не помню.
_>Так и есть. Фанаты linq что тогда были неадекватные, что сейчас.
Кто бы говорил...
_>В ответ на высказанный мимоходом очевидный тезис о тормознутости данного инструмента они начинают длинные и бесплодные дискуссии. Единственное отличие этой дискуссии от прошлой в том, что в той из реальных оценок присутствовали только слова пары человека (в том числе тебя) с форума. А в этот раз тут можно найти гораздо более интересные замеры (опять же не мои), типа таких http://liiw.blogspot.ru/2015/03/performance-of-linq-to-db-vs-entity.html.
Прекрасная статья. Сравнивается быстродействие двух Linq-провайдеров и мапперов. Получается что linq2db им практически не проигрывает. EF проигрывает, но в абсолютных велечинах речь идет о десятых долях микросекунд на объект.
G>>Давай по порядку: G>>Про быстродействие Linq G>>https://youtu.be/I2cNUUC3tiI?t=29m59s G>>Смотри внимательно на результаты.
_>Смотрю внимательно. ) Тесты в видео выглядят не особо профессионально (нет различий ни по сложности запроса, ни по результату). Но при этом дают похожие (см. первую ссылку выше) результаты.
Я на год раньше проводил замеры.
_>Довольно печальные для Linq. Правда в видео ты это очень забавно попытался обойти))) Фраза типа "всего лишь 12 мс накладных расходов — ерунда" конечно выглядит прилично... А вот если мы переозвучим её как "всего лишь 110% накладных расходов — ерунда", то она тоже будет звучать прилично? )))
Относительные величины имеют значение только для писькометрии и для запудривания мозгов.
Как в знаменитой истории "мы увеличили продажи принтеров в 27 раз. В прошлом месяце продали 1, а в этом 27"
G>>Тормоза Linq существуют в очень высоконагруженных системах, и в головах некоторых людей. _>Если ты посмотришь внимательно, то именно это (ну без добавки про головы некоторых людей) я и говорил в данной темке, причём неоднократно. Очевидно, что для всяких слабонагруженных систем linq отлично подходит. Могу показать тебе ссылки на эти сообщения, если сам не увидел. )
Я посмотрел внимательно и ты ничего про нагрузки не говорил. И вряд ли сможешь что-нить внятное сказать. У тебя высоконагруженных систем никогда не было.
Но самое главное не это, а то, что никакая система изначально не является высоконагруженной, зато любую систему надо сделать быстрее. Именно тут linq помогает.
G>>Причем в нагруженных системах легко эти тормоза обойти за счет компиляции запросов, а в головах людей эта проблема нерешаемая.
_>Ха, а вот тут уже совсем другой расклад появляется — здесь удобство становится даже похуже голых sql строк.
обоснуй
_>Я уже не говорю об инструментах из других языков, в которых есть возможность иметь полностью удобный вид без малейших накладных расходов.
В других языках нет ничего, что хотя бы на сотую долю похоже на Linq по функциональности и удобству использования.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Sinclair, Вы писали:
_>>>Я — могу. Так же как и любой, знакомый с языком SQL. ))) Ну а для неосиливших SQL действительно стоит поискать другие инструменты. ) S>> S>>Речь идёт не о том, что кто-то конкретный врукопашную неспособен соптимизировать SQL. S>>А о том, что можно декомпозировать задачу. В одном месте — определить функцию типа getAllOrders, которая возвращает все заказы, видимые текущему пользователю (...where acl.UserID = @currentUser), а в других местах (нескольких) ей пользоваться. S>>При этом в одном месте будут выводиться все детали ордера, а в другом — только подсчитываться общее количество. S>>И в результирующем sql не будет ничего лишнего — никаких join, не участвующих в выборке, никаких полей, не попавших в финальную проекцию. S>>В плохом случае вообще эти части проекта компилируются раздельно — потому что их пишут разные команды. S>>И никто вам не даст возможности руками выполнить инлайнинг и подпатчить SQL. S>>В совсем плохом случае возможность дадут, а вот денег на то, чтобы руками выписать оптимальный SQL для всех 128 вариантов сочетаний — не дадут. И неосилившим linq придётся поискать другую работу.
_>Проект с подобной архитектурой обречён быть тормозом. Соответственно это означает одно их двух: или для проекта быстродействие не критично или же изначальный архитектор проекта был некомпетентен.
Прости, а за счет чего он будет тормозом? Из-за лишних 10мс на компиляцию linq-запроса? Это надо более 100 запросов в секунду, чтобы как-то заметно влияло.
Прочитай внимательно статью, прежде чем читать дальше.
А теперь представь, что у тебя несколько таблиц таблиц, десятки параметров и десятки представлений. И тебе для каждого(!) сочетания параметров и проекций надо выписать запросы.
На моей практике linq-запрос, который собирался из 10 строк в одной простой функции, давал на выходе 80 разных SQL-запросов, каждый из которых был оптимальным под свое сочетание параметров и проекций.
Даже если ты вполне обладаешь знаниями SQL (в чем, кстати, есть сомнения), то поддерживать такое количество запросов руками — ад. Даже склейка строк не сильно поможет в такой задаче.