Здравствуйте, alex_public, Вы писали:
_>Ну а работая через linq мы получаем ту самую модную плюшку, но в обмен на уменьшение возможностей (как мы видели не полный спектр sql покрывается) и
Уменьшение возможностей пренебрежительно мало и легко компенсируется.
_>появление тормозов (существенных накладных расходов для определённых запросов).
Тормоза — это 2-5% процентов от идеального варианта. На практике мы сейчас на работе поднимаем на уши админов, что бы они устранили периодически возникающие тормоза сети и организовали вменяемое обновление статистики базы. Устранение тормозов по причине изпользования linq я даже и не припомню.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alex_public, Вы писали:
IT>>Ты для начала покажи разницу хотя бы с примерами с пейджингом, которые тебе тут уже демонстрировали. _>Это где тут была показана разница в пейджинге между postresql и sqlite? )
Если не нашёл, то могу ещё раз показать. Мне не сложно.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>>>Ты для начала покажи разницу хотя бы с примерами с пейджингом, которые тебе тут уже демонстрировали. _>>Это где тут была показана разница в пейджинге между postresql и sqlite? )
IT>Если не нашёл, то могу ещё раз показать. Мне не сложно.
Я вот сходу не могу придумать запрос, который в этих трех базах будет иметь принципиально разную структуру
Автор либы утверждает следующее
there is a misunderstanding. sqlpp11 is not an abstraction layer or an ORM. It just offers a different way of expression SQL statements. You still have to deal with all the gory details like how to join your tables, which condition to put into the WHERE and which condition to put into the HAVING part, for example. sqlpp11 does not relieve you of any of those decisions.
Получается, чисто теоретически на Sqlpp11 можно построить аналог OR/Mapper. Прямо искаропки sqlpp11 дает только SQL expression tree. Т.е. задача мягко говоря, очень нетривиальная, надо писать конвертер sql->sql
Здравствуйте, alex_public, Вы писали:
_>>>Ну вот раз у тебя есть вагон примеров на linq, то конечно же легко найдёшь среди них хотя бы один где видно отличие между упомянутыми СУБД. И тогда я легко покажу тебе соответствующую разницу в случае той библиотечки. I>>Тебе дали целый вагон таких примеров, но ты до сих пор этого не заметил I>>То самое видео, 16я минута I>>https://www.youtube.com/watch?v=m--oX73EGeQ
_>Посмотрел и 16-ую и 17-ую... Разницы между упомянутыми СУБД не вижу. Хорошо видна разница между всякой экзотикой, но у меня такие СУБД (а главное провайдеры к ним) не стоят, так что повторить данный пример и посмотреть генерируемый для них sql я не смогу. О чём я собственно тебе уже неоднократно упоминал.
Автор либы сообщил, что ты малёха приврал, процентов на 80%
there is a misunderstanding. sqlpp11 is not an abstraction layer or an ORM. It just offers a different way of expression SQL statements.
You still have to deal with all the gory details like how to join your tables, which condition to put into the WHERE and which condition to put into the HAVING part, for example. sqlpp11 does not relieve you of any of those decisions.
Собственно автор утверждает, что ты сам должен думать про джойны и тд. Собственно именно от этого linq и избавляет. Потому структура запроса сама по себе получается такой, как надо и её можно менять прямо в рантайме.
Теоретически, на sqlpp11 можно построить аналог OR/Mapper , но для этого надо написать транслятор sql->sql, ибо все что дает sqlpp11 это SQL expression tree.
Судя по тому, что для sqlpp11 написано ажно три провайдера и ни одного для серверов "большой тройки", sqlpp11 на сегодняшний день это просто затея 'я и так могу'
Глядя на код этих трех провайдеров, возникает ощущение, что они не выполняют трансформацию запроса, а просто натягивают детали синтаксиса.
То есть, все твои рассказы про sqlpp11 за последние три месяца оказались сказками. Как то так
Здравствуйте, IT, Вы писали:
I>>Вопрос можно закрывать.
IT>Т.е. чувак нас тут тролит 3 месяца, а мы только сейчас додумались глянуть вблизи на хрень, которую он приводить в качестве аргумента?
Здравствуйте, Sinclair, Вы писали:
_>>1. Не стоит мерить все РСУБД по одному SQL Server. Я уже заметил что это почему-то характерная особенность любителей linq (тут некоторые даже путали стандарт sql из-за этого), но всё же надо помнить что популярных РСУБД много и работают они весьма по разному... S>Ну, расскажите мне, какая из "многих популярных СУБД" выполняет prepared statements без помощи SQL.
Здравствуйте, IT, Вы писали:
_>>появление тормозов (существенных накладных расходов для определённых запросов). IT>Тормоза — это 2-5% процентов от идеального варианта. На практике мы сейчас на работе поднимаем на уши админов, что бы они устранили периодически возникающие тормоза сети и организовали вменяемое обновление статистики базы. Устранение тормозов по причине изпользования linq я даже и не припомню.
"2-5%" — это вообще какой-то не серьёзный разговор, подходящий разве что впаривающим что-то маркетологам. Очевидно же, что данный процент принципиально зависит от сложности запроса, размера БД, объёма возвращаемых данных и т.п. Так что в разных случаях накладные расходы могут как не превышать долей процента, так и зашкаливать за сотню процентов. Причём примеры и того и другого (с графиками измерений) уже приводились в данной теме.
Здравствуйте, IT, Вы писали:
_>>Это где тут была показана разница в пейджинге между postresql и sqlite? ) IT>Если не нашёл, то могу ещё раз показать. Мне не сложно.
Хыхы, это конечно замечательно, что спустя несколько лет периодического всплывания данной библиотечки в разных наших спорах ты всё же удосужился зайти на первую страницу её сайта. Однако странно что именно в этот момент у тебя что-то случилось со зрением и ты не смог увидеть в общем списке наличие ODBC коннектора (который соответственно может (ну точнее должен — я лично его работу не тестировал) и любимый тут SQL Server и ещё кучу других СУБД).
Что впрочем никак не меняет нашу ситуацию с тестом, т.к. у меня данный коннектор не установлен (как впрочем и от mysql).
I>Получается, чисто теоретически на Sqlpp11 можно построить аналог OR/Mapper. Прямо искаропки sqlpp11 дает только SQL expression tree. Т.е. задача мягко говоря, очень нетривиальная, надо писать конвертер sql->sql
Ты похоже забыл что такое вообще ORM. ))) Напомню, что данное понятие зародилось задолго до всяких там linq.
Здравствуйте, Ikemefula, Вы писали:
I>Автор либы сообщил, что ты малёха приврал, процентов на 80% I>... I>Собственно автор утверждает, что ты сам должен думать про джойны и тд. Собственно именно от этого linq и избавляет. Потому структура запроса сама по себе получается такой, как надо и её можно менять прямо в рантайме.
И снова у тебя какие-то проблемы со зрением. Причём очень серьёзные, поскольку про ручное выписывание всех join я говорил в сообщения выше не один раз, а уже очень много. В положительном ключе естественно, т.к. это более правильный способ работы с РСУБД. Кстати, глядя на все эти игры с join (правда это только речь про inner, в случае outer в linq вообще жуть рисуется) в linq возникает вопрос: а зачем там тогда from висит, может и его надо убрать? )))
I>Теоретически, на sqlpp11 можно построить аналог OR/Mapper , но для этого надо написать транслятор sql->sql, ибо все что дает sqlpp11 это SQL expression tree. I>Судя по тому, что для sqlpp11 написано ажно три провайдера и ни одного для серверов "большой тройки", sqlpp11 на сегодняшний день это просто затея 'я и так могу' I>Глядя на код этих трех провайдеров, возникает ощущение, что они не выполняют трансформацию запроса, а просто натягивают детали синтаксиса.
Ну так и для Linq никто в этой теме так и не смог привести примера, где join'ы меняются в зависимости от вида СУБД. Более того, из одного из спецов по Linq в итоге удалось выжать признание, что "подобного кода сейчас вроде нет, но его можно легко добавить". Ну как бы добавить то везде можно, если зачем-то очень понадобится... )))
Здравствуйте, IT, Вы писали:
_>>"2-5%" — это вообще какой-то не серьёзный разговор, IT>Именно. 2-5% — это только чтобы пощадить твои чувства. По максимуму тем, чем можно пренебречь.
Здравствуйте, alex_public, Вы писали:
S>>Ну, расскажите мне, какая из "многих популярных СУБД" выполняет prepared statements без помощи SQL.
_>Ну например в той же mysql http://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html, которая будет попопулярнее вашего любимого SQL Server. ))) Я уже не говорю о том, что sqlite и т.п. встроенные решения априори работают в данном моменте без sql. )))
Это какая то глупая шутка. В качестве примера "без помощи SQL" ты показал "PREPARE, EXECUTE, and DEALLOCATE PREPARE Statements"
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt2 FROM @s;
SET @a = 6;
SET @b = 8;
EXECUTE stmt2 USING @a, @b;
DEALLOCATE PREPARE stmt2;
Первые две строчки выполнятся один раз. Остальное — каждый раз. И все это SQL. Да-да.
Здравствуйте, alex_public, Вы писали:
_>Ну например в той же mysql http://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html, которая будет попопулярнее вашего любимого SQL Server.
Ну да, всё правильно. В сервер уезжает стеймент EXECUTE. Который парсится на общих основаниях.
Всё ровно точно так же, как и в моём любимом SQL Server. И в Postgres, к слову, также.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
I>>Собственно автор утверждает, что ты сам должен думать про джойны и тд. Собственно именно от этого linq и избавляет. Потому структура запроса сама по себе получается такой, как надо и её можно менять прямо в рантайме.
_>И снова у тебя какие-то проблемы со зрением. Причём очень серьёзные, поскольку про ручное выписывание всех join я говорил в сообщения выше не один раз, а уже очень много. В положительном ключе естественно, т.к. это более правильный способ работы с РСУБД.
А вот с объектной моделью это совсем не правильный способ.
>Кстати, глядя на все эти игры с join (правда это только речь про inner, в случае outer в linq вообще жуть рисуется) в linq возникает вопрос: а зачем там тогда from висит, может и его надо убрать? )))
Не ясно, где ты жуть увидел.
var q =
from c in categories
join p in products on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };
I>>Теоретически, на sqlpp11 можно построить аналог OR/Mapper , но для этого надо написать транслятор sql->sql, ибо все что дает sqlpp11 это SQL expression tree. I>>Судя по тому, что для sqlpp11 написано ажно три провайдера и ни одного для серверов "большой тройки", sqlpp11 на сегодняшний день это просто затея 'я и так могу' I>>Глядя на код этих трех провайдеров, возникает ощущение, что они не выполняют трансформацию запроса, а просто натягивают детали синтаксиса.
_>Ну так и для Linq никто в этой теме так и не смог привести примера, где join'ы меняются в зависимости от вида СУБД.
Тебе показали, что для разных баз структура запросов может быть разная.
>Более того, из одного из спецов по Linq в итоге удалось выжать признание, что "подобного кода сейчас вроде нет, но его можно легко добавить". Ну как бы добавить то везде можно, если зачем-то очень понадобится... )))
Врёшь. IT несколько раз пояснил, какие оптимизации выполняются.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Ikemefula, Вы писали:
I>>Вообще, sqlpp11 умеет всего ажно три базы I>>MySQL: https://github.com/rbock/sqlpp11-connector-mysql I>>Sqlite3: https://github.com/rbock/sqlpp11-connector-sqlite3 I>>PostgreSQL: https://github.com/matthijs/sqlpp11-connector-postgresql
_>Хыхы, это конечно замечательно, что спустя несколько лет периодического всплывания данной библиотечки в разных наших спорах ты всё же удосужился зайти на первую страницу её сайта. Однако странно что именно в этот момент у тебя что-то случилось со зрением и ты не смог увидеть в общем списке наличие ODBC коннектора (который соответственно может (ну точнее должен — я лично его работу не тестировал) и любимый тут SQL Server и ещё кучу других СУБД).
Экспериментальный коннектор версия 0.01, кушай сам. Кроме того, он тоже не умеет ничего тобой заявленого. Фактически — просто натягивает синтаксис на фиксированую структуру.
I>>Получается, чисто теоретически на Sqlpp11 можно построить аналог OR/Mapper. Прямо искаропки sqlpp11 дает только SQL expression tree. Т.е. задача мягко говоря, очень нетривиальная, надо писать конвертер sql->sql
_>Ты похоже забыл что такое вообще ORM. ))) Напомню, что данное понятие зародилось задолго до всяких там linq.
1 Автор sqlpp11 утверждает, что sqlpp11 не является OR/Mapper.
2 современный OR/Mapper в обязательном порядке использует язык запросов.
3 В дотнет такой язык как правило реализуется через linq, ибо искаропки получается унификация интерфейса со всеми остальными либами чз IQueryable.
Пример — на платформе Java hibernate использует HQL
Hibernate Query Language (HQL) is an object-oriented query language, similar to SQL, but instead of operating on tables and columns, HQL works with persistent objects and their properties
Здравствуйте, alex_public, Вы писали: _>Ну так если ты настаиваешь, что 5% — это самый большой возможный уровень накладных расходов у linq2db, то как ты тогда объясняешь 90% в данном http://liiw.blogspot.ru/2015/03/performance-of-linq-to-db-vs-entity.html тесте (случай Simple TOP 10 query)?
Это объясняется тем, что я вообще не понимаю что тестируют эти тесты. Вот мой тест:
Скрытый текст
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using DataModels;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
var sw = new Stopwatch();
LinqTest(sw);
AdoTest(sw);
var n = LinqTest(sw);
Console.WriteLine("LINQ: {0} in {1}", n, sw.Elapsed);
n = AdoTest(sw);
Console.WriteLine("ADO: {0} in {1}", n, sw.Elapsed);
}
static int LinqTest(Stopwatch sw)
{
sw.Reset();
var count = 0;
using (var ctx = new NorthwindDB())
{
for (var i = 0; i < 10000; i++)
{
sw.Start();
var list =
(
from o in ctx.Orders
join c in ctx.Customers on o.CustomerID equals c.CustomerID
select new { o.OrderID, o.OrderDate, c.Country, c.CompanyName }
).Take(10).ToList();
sw.Stop();
count += list.Count;
}
}
return count;
}
static int AdoTest(Stopwatch sw)
{
sw.Reset();
var count = 0;
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString))
{
con.Open();
for (var i = 0; i < 10000; i++)
{
sw.Start();
var list = new List<object>();
using (var cmd = new SqlCommand(@"
SELECT TOP (10)
[o].[OrderID],
[o].[OrderDate],
[c].[Country],
[c].[CompanyName]
FROM
[dbo].[Orders] [o]
INNER JOIN [dbo].[Customers] [c] ON [o].[CustomerID] = [c].[CustomerID]", con))
{
using (var reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
list.Add(new
{
OrderID = (int)reader["OrderID"],
OrderDate = (DateTime)reader["OrderDate"],
Country = (string)reader["Country"],
CompanyName = (string)reader["CompanyName"],
});
}
}
}
}
sw.Stop();
count += list.Count;
}
}
return count;
}
}
}
Отличается от предыдущих тем, что более менее отражает реалии жизни. Во-первых, БД находится на другой машине. Во-вторых, в реальности на ADO.NET так никто не пишет. Ни один вменяемый разработчик не будет использовать индексы вместо имён полей. Такой код живёт ровно до первого изменения.
Результат:
LINQ: 100000 in 00:00:05.7321425
ADO: 100000 in 00:00:05.5328326
Разница в районе одного процента туда суда. А если я ещё добавлю в тест ADO.NET проверку на DBNull, то он вообще может оказаться медленнее. _>P.S. Да, данная ссылка уже не раз всплывала в данной дискуссии, но что же делать, если продолжаются утверждения типа "максимум 2-5%"? )
Ну это как обычно в этой теме. Все обсуждают ссылку, а проверить её качество никто до сих пор не удосужился.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alex_public, Вы писали:
_>>>Это где тут была показана разница в пейджинге между postresql и sqlite? )
Вот что генерируется для разных баз. Для туповатых Access и Sybase Skip реализуется на клиенте.
-- AccessSELECT TOP 7
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC-- DB2 DB2.LUW DB2LUWSELECT *
FROM
(
SELECT
t.*,
ROW_NUMBER() OVER() as rn
FROM
(
SELECT
"t1"."ParentID",
"t1"."ChildID"
FROM
"Child" "t1"
ORDER BY
"t1"."ChildID" DESC
) t
) t2
WHERE
t2.rn BETWEEN 3 AND 7
-- FirebirdSELECT FIRST 5 SKIP 2
t1.ParentID,
t1.ChildID
FROM
Child t1
ORDER BY
t1.ChildID DESC-- InformixSELECT SKIP 2 FIRST 5
t1.ParentID,
t1.ChildID
FROM
Child t1
ORDER BY
t1.ChildID DESC-- MariaDB MySqlSELECT
`t1`.`ParentID`,
`t1`.`ChildID`
FROM
`Child` `t1`
ORDER BY
`t1`.`ChildID` DESC
LIMIT 2,5
-- MySqlSELECT
`t1`.`ParentID`,
`t1`.`ChildID`
FROM
`Child` `t1`
ORDER BY
`t1`.`ChildID` DESC
LIMIT 2,5
-- Oracle.Native OracleSELECT t2.*
FROM
(
SELECT t.*, ROWNUM as rn
FROM
(
SELECT
t1.ParentID,
t1.ChildID
FROM
Child t1
ORDER BY
t1.ChildID DESC
) t
WHERE
ROWNUM <= 7
) t2
WHERE
t2.rn > 2
-- PostgreSQL PostgreSQL.9.3 PostgreSQLSELECT
t1."ParentID",
t1."ChildID"
FROM
"Child" t1
ORDER BY
t1."ChildID" DESC
LIMIT 5 OFFSET 2
-- SQLiteSELECT
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC
LIMIT 5 OFFSET 2
-- SqlAzure.2012 SqlServer.2012SELECT
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY
-- SqlCeSELECT
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY
-- SqlServer.2005SELECT *
FROM
(
SELECT
t.*,
ROW_NUMBER() OVER
(
ORDER BY
oby DESC
) as rn
FROM
(
SELECT
[t1].[ParentID],
[t1].[ChildID],
[t1].[ChildID] as [oby]
FROM
[Child] [t1]
) t
) t2
WHERE
t2.rn BETWEEN 3 AND 7
-- SqlServer.2008SELECT *
FROM
(
SELECT
t.*,
ROW_NUMBER() OVER
(
ORDER BY
oby DESC
) as rn
FROM
(
SELECT
[t1].[ParentID],
[t1].[ChildID],
[t1].[ChildID] as [oby]
FROM
[Child] [t1]
) t
) t2
WHERE
t2.rn BETWEEN 3 AND 7
-- SqlServer.2012SELECT
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY
-- SqlServer.2014 SqlServer.2012SELECT
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY
-- SybaseSELECT TOP 7
[t1].[ParentID],
[t1].[ChildID]
FROM
[Child] [t1]
ORDER BY
[t1].[ChildID] DESC
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
_>>P.S. Да, данная ссылка уже не раз всплывала в данной дискуссии, но что же делать, если продолжаются утверждения типа "максимум 2-5%"? ) IT>Ну это как обычно в этой теме. Все обсуждают ссылку, а проверить её качество никто до сих пор не удосужился.
По ссылке время замеряется вместе с инициализацией контекста\открытием соединения, а у тебя — только время запросов.