Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 重构过热的T-SQL查询_Sql Server_Performance_Tsql_Refactoring - Fatal编程技术网

Sql server 重构过热的T-SQL查询

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 ,

有没有办法重构此查询,使其不再进行如此多的GetRemainingAmount(@Id)函数调用?我尝试在select块中命名它,例如Amount,然后在Where和Group中使用它的编译错误

 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。分组依据
仍然可以消除重复项,但似乎可以用不同的替换。