Sql 如何替换函数以加快查询速度?

Sql 如何替换函数以加快查询速度?,sql,sql-server,Sql,Sql Server,我尝试在不使用function的情况下进行查询,因为它需要花费太多的时间才能给出结果。这是包含函数和结果的代码 SELECT LEFT(D2.D2_EMISSAO,6), F2.F2_VEND1, SUM((D2.D2_TOTAL-dbo.UCOMPRA(D2.D2_COD, D2.D2_EMISSAO)*D2.D2_QUANT)) AS LUCRO_LIQ FROM SD2010 D2 INNER JOIN SF2010 F2 ON D2.D2_

我尝试在不使用function的情况下进行查询,因为它需要花费太多的时间才能给出结果。这是包含函数和结果的代码

SELECT  
LEFT(D2.D2_EMISSAO,6),
F2.F2_VEND1,
SUM((D2.D2_TOTAL-dbo.UCOMPRA(D2.D2_COD, D2.D2_EMISSAO)*D2.D2_QUANT)) AS  LUCRO_LIQ
FROM SD2010 D2                
INNER JOIN SF2010 F2 
    ON D2.D2_DOC = F2.F2_DOC AND D2.D2_SERIE = F2.F2_SERIE AND F2.D_E_L_E_T_= ''
WHERE 
D2.D2_EMISSAO >=  '20171201'
AND D2.D2_TES IN ('502','506')
GROUP BY 
LEFT(D2.D2_EMISSAO,6),
F2.F2_VEND1
ORDER BY F2.F2_VEND1 DESC
这就是功能:

ALTER FUNCTION dbo.UCOMPRA( @CODIGO VARCHAR(25), @DATE VARCHAR(8))
RETURNS float

 BEGIN
 DECLARE @UPRECO float;

    SELECT TOP 1 @UPRECO = ROUND(D1.D1_CUSTO/D1.D1_QUANT,2)
    FROM SD1010 D1  
   WHERE D1.D_E_L_E_T_ = ''        
       AND D1.D1_TES  IN('015','202','205','206')
           AND D1.D1_COD = @CODIGO 
           AND D1.D1_EMISSAO <= @DATE 
      ORDER BY D1.D1_EMISSAO DESC ;  

RETURN ROUND(@UPRECO,2);
END;
GO
函数的查询结果

我试过这个:

SELECT  D2.D2_EMISSAO,
D2.D2_DOC,
D2.D2_COD,
D2.D2_QUANT,
D2.D2_PRCVEN, 
D2.D2_TOTAL, 
ENTRADA.CUSTO,
((D2.D2_TOTAL/D2.D2_QUANT-ENTRADA.CUSTO)*D2.D2_QUANT) AS  LUCRO_LIQ

FROM SD2010 D2
LEFT JOIN SD1010 D1 ON D2.D2_COD=D1.D1_COD
INNER JOIN (SELECT D1.D1_COD AS COD,D1.D1_TOTAL AS D1TOTAL, 
D1.D1_TOTAL/D1.D1_QUANT AS CUSTO
        FROM SD1010 D1 
        WHERE 
        D1.D1_EMISSAO <= '20171201'
        AND D1.D1_TES IN ('015','202','205','206')
        AND D1.D_E_L_E_T_='') ENTRADA
        ON D2.D2_COD = ENTRADA.COD


  WHERE D2.D2_COD = '000712S3B70340'
  AND D1.D1_EMISSAO <= D2.D2_EMISSAO
  AND D2.D2_TES IN ('502','506')
  ORDER BY D2.D2_DOC DESC

结果上的差异是因为在函数中使用了Order by,但在sub select中并没有Order by。此外,通过内部子选择添加订单也没有任何意义

与标量函数相比,我更喜欢内联表值函数


对不起,我没有理解,您提到的订单是代码中没有函数的订单?该选项不在子选项中。另外,如果我将函数更改为内联表值,代码的速度会提高吗?@cthulhu-内联表值将比当前的标量函数快得多。与内联函数不同,将为每一行调用标量函数。。检查这篇文章,谢谢它的工作!但是你能告诉我oa是什么吗?@cthulhu-oa是外部应用中使用的函数dbo.Ucompra的别名
DROP FUNCTION dbo.Ucompra

go

CREATE FUNCTION dbo.Ucompra(@CODIGO VARCHAR(25),
                            @DATE   VARCHAR(8))
RETURNS TABLE
    RETURN
      (SELECT TOP 1 UPRECO = Round(D1.D1_CUSTO / D1.D1_QUANT, 2)
       FROM   SD1010 D1
       WHERE  D1.D_E_L_E_T_ = ''
              AND D1.D1_TES IN( '015', '202', '205', '206' )
              AND D1.D1_COD = @CODIGO
              AND D1.D1_EMISSAO <= @DATE
       ORDER  BY D1.D1_EMISSAO DESC)

GO

SELECT LEFT(D2.D2_EMISSAO, 6),
       F2.F2_VEND1,
       Sum(( D2.D2_TOTAL - oa.UPRECO * D2.D2_QUANT )) AS LUCRO_LIQ
FROM   SD2010 D2
       INNER JOIN SF2010 F2
               ON D2.D2_DOC = F2.F2_DOC
                  AND D2.D2_SERIE = F2.F2_SERIE
                  AND F2.D_E_L_E_T_ = ''
       OUTER apply dbo.Ucompra(D2.D2_COD, D2.D2_EMISSAO) oa
WHERE  D2.D2_EMISSAO >= '20171201'
       AND D2.D2_TES IN ( '502', '506' )
GROUP  BY LEFT(D2.D2_EMISSAO, 6),
          F2.F2_VEND1
ORDER  BY F2.F2_VEND1 DESC