Sql server 重构过热的T-SQL查询
有没有办法重构此查询,使其不再进行如此多的GetRemainingAmount(@Id)函数调用?我尝试在select块中命名它,例如Amount,然后在Where和Group中使用它的编译错误Sql server 重构过热的T-SQL查询,sql-server,performance,tsql,refactoring,Sql Server,Performance,Tsql,Refactoring,有没有办法重构此查询,使其不再进行如此多的GetRemainingAmount(@Id)函数调用?我尝试在select块中命名它,例如Amount,然后在Where和Group中使用它的编译错误 SELECT SomeAccountId , GetRemainingAmount(@Id) , Iso FROM Accounts WHERE GetRemainingAmount(@Id) > 0 GROUP BY SomeAccountId ,
SELECT SomeAccountId ,
GetRemainingAmount(@Id) ,
Iso
FROM Accounts
WHERE GetRemainingAmount(@Id) > 0
GROUP BY SomeAccountId ,
GetRemainingAmount(@Id) ,
Iso
您总是可以这样做,使用CTE(公共表表达式)隔离该调用,并且只执行一次:
;WITH CTE AS
(
SELECT
SomeAccountId,
RemainingAmount = GetRemainingAmount(@Id),
Iso
FROM
Accounts
)
SELECT
SomeAccountId, RemainingAmount, Iso
FROM
CTE
WHERE
RemainingAmount > 0
GROUP BY
SomeAccountId,
RemainingAmount,
Iso
但老实说,如果没有像
SUM
或AVG
这样的聚合函数,我首先看不出GROUP BY
子句的意义….可以使用distinct来消除GROUP BY
SELECT distinct
SomeAccountId ,
GetRemainingAmount(@Id) ,
Iso
FROM Accounts
WHERE GetRemainingAmount(@Id) > 0
或者你也可以从中得出:
select
SomeAccountId,
RemainingAmount,
Iso
from (
SELECT
SomeAccountId,
GetRemainingAmount(@Id) as RemainingAmount,
Iso
FROM Accounts
) _Data
WHERE RemainingAmount > 0
GROUP BY
SomeAccountId,
RemainingAmount,
Iso
粘贴
GetRemainingAmount()
SELECT中的交叉应用代码将在一个字段中给出结果,然后可以在WHERE/groupby中使用;粘贴不会改变任何东西,GetRemainingAmount是一个耗时的函数,我希望避免重复调用它。WHERE
子句中的标量UDF是一个反模式。您没有其他谓词,因此它将始终对帐户中的每一行求值。如果你给我们看它的代码,我们可能会建议一个替代方案。马丁·史密斯提出了最重要的一点。您可以减少键入该代码的次数,但where子句只会在为所有行运行该函数后删除行。在计算每行的金额之前,不可能知道金额是否大于0。分组依据
仍然可以消除重复项,但似乎可以用不同的替换。