Переиспользование вычислений в linq2db
От: STDray http://stdray.livejournal.com
Дата: 22.08.18 16:05
Оценка:
Привет!


Есть, например, вот такой искусственный запрос
from cla in P2P_CALCULATED_CESSION_LOAN_ACCRUE
let cessionStartPlus2 = cla.CessionStart.AddDays(2)
let x = P2P_CALCULATED_CESSION_LOAN_ACCRUE.Sum(y => y.InvestorInterest)
select new
{
    Y1 = x < 0 ? 9 : x + 8,
    Y2 = Math.Round(x + x)
};


он раскрывается вот портянку, где вычисление x будет повторено несколько раз

SELECT
    CASE
        WHEN (
            SELECT
                Sum([t1].[InvestorInterest])
            FROM
                [dbo].[P2P_CALCULATED_CESSION_LOAN_ACCRUE] [t1]
        ) < 0
            THEN 9
        ELSE (
            SELECT
                Sum([t1].[InvestorInterest])
            FROM
                [dbo].[P2P_CALCULATED_CESSION_LOAN_ACCRUE] [t1]
        ) + 8
    END as [c2],
    (
        SELECT
            Sum([t2].[InvestorInterest])
        FROM
            [dbo].[P2P_CALCULATED_CESSION_LOAN_ACCRUE] [t2]
    ) as [c4]
FROM
    [dbo].[P2P_CALCULATED_CESSION_LOAN_ACCRUE] [t3]


Есть ли какой-то способ вместо прямой подстановки сгенерировать запрос с внешним select?
Что-то вроде такого
select 
    CASE WHEN t1.x < 0 THEN 9 ELSE t1.x + 8 END as [c2],
    Round(t1.x  + t1.x, 2) as [c4]
from (SELECT Sum([InvestorInterest]) as x FROM    [dbo].[P2P_CALCULATED_CESSION_LOAN_ACCRUE]) [t1]


Может как-то руками можно указать, что в данном случае надо x не раскрывать, а один раз вычислить и дальше оборачивать внещними селектами?
Re: Переиспользование вычислений в linq2db
От: Слава  
Дата: 22.08.18 16:19
Оценка:
Здравствуйте, STDray, Вы писали:

STD>Есть, например, вот такой искусственный запрос

STD>Может как-то руками можно указать, что в данном случае надо x не раскрывать, а один раз вычислить и дальше оборачивать внещними селектами?

Как мне кажется, это только через СTE. В самом-то SQL выражения между SELECT (....) as Col1 ... ORDER BY Col1 не всегда можно переиспользовать.
Re[2]: Переиспользование вычислений в linq2db
От: STDray http://stdray.livejournal.com
Дата: 22.08.18 16:53
Оценка:
Здравствуйте, Слава, Вы писали:

С>Как мне кажется, это только через СTE. В самом-то SQL выражения между SELECT (....) as Col1 ... ORDER BY Col1 не всегда можно переиспользовать.


В том-то и дело, что в этом случае надо делать select Comp1(x) as A1, Comp2(x) as A2, ... from (select SOME_HUGE_CALCULATION as x from ...).
Во внутреннем селекте выражение связывается с именем, а во внешнем уже используется его значение.
Отредактировано 22.08.2018 16:55 STDray . Предыдущая версия .
Re[2]: Переиспользование вычислений в linq2db
От: MadHuman Россия  
Дата: 23.08.18 10:20
Оценка:
Здравствуйте, Слава, Вы писали:

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


STD>>Есть, например, вот такой искусственный запрос

STD>>Может как-то руками можно указать, что в данном случае надо x не раскрывать, а один раз вычислить и дальше оборачивать внещними селектами?
а в этом есть смысл? sql server разве не опознаёт одинаковы подвыражения и не устраняет их повторные вычисления?
Re[3]: Переиспользование вычислений в linq2db
От: STDray http://stdray.livejournal.com
Дата: 23.08.18 14:21
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>а в этом есть смысл? sql server разве не опознаёт одинаковы подвыражения и не устраняет их повторные вычисления?


в этом есть смысл.
я смотрел план того простого примера из открывающего поста, там будет 3 отдельных подзапроса.
вообщем, никакие повторные вычисления не устраняются.
Re: Переиспользование вычислений в linq2db
От: STDray http://stdray.livejournal.com
Дата: 29.08.18 15:11
Оценка:
STD>Может как-то руками можно указать, что в данном случае надо x не раскрывать, а один раз вычислить и дальше оборачивать внешними селектами?

неужели никто ни сталкивался с подобной проблемой?
есть ли какие-то концептуальные проблемы, которые мешают генерировать селекты над селектами вместо полной подстановки выражения?
Re[2]: Переиспользование вычислений в linq2db
От: Danchik Украина  
Дата: 04.09.18 17:49
Оценка: +1
Здравствуйте, STDray, Вы писали:

STD>>Может как-то руками можно указать, что в данном случае надо x не раскрывать, а один раз вычислить и дальше оборачивать внешними селектами?


STD>неужели никто ни сталкивался с подобной проблемой?

STD>есть ли какие-то концептуальные проблемы, которые мешают генерировать селекты над селектами вместо полной подстановки выражения?

Вот почему не писать linq выражения точно так же как и SQL? Знали бы каких усилий стоит разобрать что пользователь хочет от этого let — его в SQL нет!
from x in (
   from cla in P2P_CALCULATED_CESSION_LOAN_ACCRUE
   select Sql.Ext.Sum(cla.InvestorInterest).ToValue()
)
select new
{
    Y1 = x < 0 ? 9 : x + 8,
    Y2 = Math.Round(x + x)
};
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.