Sql 优化查询

Sql 优化查询,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有以下功能 CREATE FUNCTION [dbo].[SuiviRupture] (@CodeArticle [NVARCHAR](13), @CodeSite [NVARCHAR](5), @CodeStructure [NVARCHAR](13)) RETURNS @calcul TABLE (CAMOY FLOAT, QTEMOY FLOAT) AS BEGIN WITH temp AS ( SELECT

我有以下功能

CREATE FUNCTION [dbo].[SuiviRupture]
    (@CodeArticle [NVARCHAR](13),
     @CodeSite [NVARCHAR](5), 
     @CodeStructure [NVARCHAR](13))
RETURNS @calcul TABLE (CAMOY FLOAT, QTEMOY FLOAT)
AS 
BEGIN
    WITH temp AS 
    (
        SELECT 
            t1.[datecol], t1.[Prix de vente TTC],
            t1.Quantité 
        FROM 
            [V_VentePromo] t1
        INNER JOIN 
            (SELECT DISTINCT 
                 [datecol], [Code Article], [Code Structure],
                 [Code Site], 
                 ROW_NUMBER() OVER(PARTITION BY [Code Article], [Code Structure], [Code Site] 
                                   ORDER BY [datecol] DESC) AS rn
             FROM 
                 (SELECT DISTINCT  
                      [datecol], [Code Article], [Code Structure], [Code Site]
                  FROM 
                      [V_VentePromo] t2
                  WHERE 
                      [Code Article] = @CodeArticle 
                      AND [Code Site] = @CodeSite 
                      AND [Code Structure] = @CodeStructure) g
          ) a ON a.datecol = t1.datecol
                 AND t1.[Code Article] = a.[Code Article]
                 AND t1.[Code Structure] = a.[Code Structure]
                 AND t1.[Code Site] = a.[Code Site]
        WHERE 
            t1.[Code Article] = @CodeArticle 
            AND t1.[Code Site] = @CodeSite 
            AND t1.[Code Structure] = @CodeStructure
            AND rn <= 28
    )
    INSERT @calcul 
        SELECT
            CASE WHEN COUNT(distinct [datecol]) = 0 
                    THEN 0 
                    ELSE SUM(convert(float, Quantité)) / count(distinct [datecol]) 
            END as QTEMOY,
            CASE WHEN COUNT(distinct [datecol]) = 0 
                    THEN 0 
                    ELSE SUM(convert(float, [Prix de vente TTC])) / count(distinct [datecol]) 
            END AS CAMOY
        FROM 
            temp
     RETURN;
END;

执行时间太长,我有多行V_distinctVente约10000。如何优化它?我如何将主查询与TVF的T-SQL代码组合在一个查询中?它在主查询中逐行执行

您的函数可以很容易地转换为内联TVF。带有BEGIN…END的老式TVF需要一个表的声明,并且以非常糟糕的性能而闻名

其他内联TVF或特设TVF:这是完全内联的,其行为类似于视图。试着这样做:

CREATE FUNCTION [dbo].[SuiviRupture](@CodeArticle [NVARCHAR](13),@CodeSite [NVARCHAR](5) ,@CodeStructure [NVARCHAR](13))
RETURNS TABLE 
AS 
RETURN
WITH temp AS (
 SELECT t1.[datecol],t1.[Prix de vente TTC],t1.Quantité 
      FROM [V_VentePromo] t1
      INNER JOIN (SELECT DISTINCT [datecol],[Code Article],[Code Structure],[Code Site],
      ROW_NUMBER() OVER(PARTITION BY  [Code Article],[Code Structure],[Code Site] ORDER BY [datecol]desc ) AS rn

      FROM (SELECT DISTINCT  [datecol],[Code Article],[Code Structure],[Code Site]
           FROM [V_VentePromo] t2
            WHERE [Code Article]= @CodeArticle AND [Code Site]=@CodeSite AND [Code Structure]=@CodeStructure
    )g
          ) a
           ON a.datecol=t1.datecol
            AND t1.[Code Article] = a.[Code Article]
            AND t1.[Code Structure]=a.[Code Structure]
            AND t1.[Code Site]=a.[Code Site]
            WHERE   t1.[Code Article]= @CodeArticle AND t1.[Code Site]=@CodeSite AND t1.[Code Structure]=@CodeStructure
            AND  rn <= 28

)
SELECT 

    CASE WHEN COUNT(DISTINCT [datecol])  =0 THEN 0 ELSE   SUM(CONVERT(FLOAT,Quantité))/COUNT(DISTINCT [datecol]) END  AS QTEMOY
    ,  CASE WHEN COUNT(DISTINCT [datecol])  =0 THEN 0 ELSE  SUM(CONVERT(FLOAT,[Prix de vente TTC])) / COUNT(DISTINCT [datecol])END AS CAMOY
FROM temp
;
GO

你没有在这里发布太多的细节。你知道你的函数列是颠倒的吗?您将表定义为CAMOY,QTEMOY,但插入是另一种方式。我有点担心你的表值函数。它在那里有两次相同的视图。那个视图是什么样子的?还有一个外部视图,它看起来像什么?你有嵌套视图吗?发布实际执行计划而不是部分屏幕截图怎么样?@SeanLange如何发布所有执行计划?发布执行计划时,首先保存它,然后将其附加到您的帖子中。我尝试了。它几乎同时执行。我能把函数转换成存储过程吗?否则会更糟吗?不,即席SQL会更快。试着取出部分,找出损失时间最多的地方……我怎么能将主查询与TVF的T-SQL代码组合在一个查询中?它在主查询中逐行执行
CREATE FUNCTION [dbo].[SuiviRupture](@CodeArticle [NVARCHAR](13),@CodeSite [NVARCHAR](5) ,@CodeStructure [NVARCHAR](13))
RETURNS TABLE 
AS 
RETURN
WITH temp AS (
 SELECT t1.[datecol],t1.[Prix de vente TTC],t1.Quantité 
      FROM [V_VentePromo] t1
      INNER JOIN (SELECT DISTINCT [datecol],[Code Article],[Code Structure],[Code Site],
      ROW_NUMBER() OVER(PARTITION BY  [Code Article],[Code Structure],[Code Site] ORDER BY [datecol]desc ) AS rn

      FROM (SELECT DISTINCT  [datecol],[Code Article],[Code Structure],[Code Site]
           FROM [V_VentePromo] t2
            WHERE [Code Article]= @CodeArticle AND [Code Site]=@CodeSite AND [Code Structure]=@CodeStructure
    )g
          ) a
           ON a.datecol=t1.datecol
            AND t1.[Code Article] = a.[Code Article]
            AND t1.[Code Structure]=a.[Code Structure]
            AND t1.[Code Site]=a.[Code Site]
            WHERE   t1.[Code Article]= @CodeArticle AND t1.[Code Site]=@CodeSite AND t1.[Code Structure]=@CodeStructure
            AND  rn <= 28

)
SELECT 

    CASE WHEN COUNT(DISTINCT [datecol])  =0 THEN 0 ELSE   SUM(CONVERT(FLOAT,Quantité))/COUNT(DISTINCT [datecol]) END  AS QTEMOY
    ,  CASE WHEN COUNT(DISTINCT [datecol])  =0 THEN 0 ELSE  SUM(CONVERT(FLOAT,[Prix de vente TTC])) / COUNT(DISTINCT [datecol])END AS CAMOY
FROM temp
;
GO