查询优化-花费很长时间

时间:2019-04-27 10:06:05

标签: sql sql-server view

我有这个查询,显示截至当前日期前24个月的营业额。

我正在使用SQL SERVER 2008,我的问题是我的查询需要很长时间才能执行。

我正在使用2个表:Etablissement以获得商店名称,而piece则获得每个部门的营业额之和。 结果: enter image description here

this._router.navigate(['adminLogin'], {relativeTo: this.acRoute})

有什么解决方案可以优化我的查询?

3 个答案:

答案 0 :(得分:0)

这是注释部分不适合的注释。

我知道您正在进行多个查询,并且查询速度越来越慢。让我们一次取一个。例如:

select CONVERT(DECIMAL(15,2),sum(gl_totalttcdev)) 
from piece 
left join ligne on gl_souche = gp_souche 
               and gl_naturepieceg = gp_naturepieceg and gl_numero=gp_numero 
               and gl_indiceg = gp_indiceg 
left join etabliss as e on gp_etablissement = et_etablissement 
left join ARTICLE on GL_CODEARTICLE = ARTICLE.GA_CODEARTICLE
where gp_naturepieceg = 'FFO' 
  and year(gp_datepiece) = year(DATEADD(MONTH,-1,GETDATE()))
  and  month(gp_datepiece) =  MONTH( DATEADD(MONTH,-1,GETDATE())) 
  and gl_typearticle <> ''
  and gl_typearticle <> 'FI' 
  and ETAB.ET_ETABLISSEMENT = e.ET_ETABLISSEMENT
  and ETAB.ET_LIBELLE = e.ET_LIBELLE
group by gp_etablissement, et_libelle

首先,为了优化它,对于我们来说知道每一列从何而来至关重要。因此... 为您提到的所有列添加前缀。我们真的无法猜测每一列的表格。

答案 1 :(得分:0)

对于每条记录,执行这两个函数year(DATEADD(MONTH,-1,GETDATE()))MONTH( DATEADD(MONTH,-1,GETDATE()))时,它始终给出一个常量值,将这些值存储在变量中,并在查询中使用这些变量将有助于提高速度。

答案 2 :(得分:0)

您所写的查询非常令人困惑,并且可能为什么只有一个提供了解决方案。现在,让我们尝试简化并阐明您的要求。如果有任何不正确之处,请纠正我。

您需要一个查询,该查询显示最近13个月期间的总计(按每个组) 商店代码。第一个月代表当前月份和之前的13个月(或您指定的24个月)之前的月份。

现在查询。您正在从ETABLISS表中进行查询,并按gp_etablisssement,et_libelle进行分组。
通过谷歌将法语翻译成英语

Etablissement = Establishement
Libelle = Wording

所以我在猜测,您的分配更多是唯一的ID密钥,而Libelle是要显示给定分配的标签。

Ex: 
etablissement   libelle
1               Business A
2               Business B
3               Business C

因此标签将始终与etablissement(ID)字段直接相关。

首先简化。您需要使用筛选器对所有符合条件的所有linge值求和。首先,计件表是日期范围标准的基础。计件表具有您最终想要分组的分配字段

select
        p.gp_etablissement,
        sum(l.gl_totalttcdev) SumPerEtablissement
    from
        Piece P
            JOIN Linge L
                -- all criteria specifically limiting the LINGE records
                on P.gp_souche = L.gl_souche 
                and p.gp_naturepieceg = l.gl_naturepieceg 
                and p.gp_numero = l.gl_numero
                and p.gp_indiceg = l.gl_indiceg
                and l.gl_typearticle <> ''
                and l.gl_typearticle <> 'FI' 
    where
        -- simple to get all records for past 13 months for now just to show summary
        p.gp_DatePiece > dateadd( month, -13, getdate())
    group by
        p.gp_etablissement

因此,从上方看,每个机构都有一个结果表,其中包含整个13个月的总数。现在,您希望它每个月细分一次...添加一个额外的列,将月份/年份显示为一列并分组。当我们在这里时,我们可以加入到etablissement表中,以提取您可能想要显示的描述/标签。

我要输入的另一个项目是与当前日期的月份差,因此我们总是有一个固定的顺序来组织总计。使用DateDiff()。这将有助于您获得关键的结果,从而将每个数据集的所有数据拉到一行。

select
        p.gp_etablissement,
        e.et_libelle,
        -- Example: 2019-04-27 would return '2019-04-27'
        CONVERT(CHAR(7),p.gp_DatePiece,120) as YrMonth,
        -- nice thing about datediff by month.  It properly detects
        -- '2019-04-01' from '2019-03-31' as 1 month apart even though 1 day
        -- so ANY Date within the YrMonth will be within the given month.
        min( datediff( month, p.gp_DatePiece, getdate() )) as MonthsPrior,
        -- now the column getting summed
        sum(l.gl_totalttcdev) SumPerEtabliss
    from
        Piece P
            JOIN Linge L
                -- all criteria specifically limiting the LINGE records
                on P.gp_souche = L.gl_souche 
                and p.gp_naturepieceg = l.gl_naturepieceg 
                and p.gp_numero = l.gl_numero
                and p.gp_indiceg = l.gl_indiceg
                and l.gl_typearticle <> ''
                and l.gl_typearticle <> 'FI' 
            JOIN Etabliss e
                on p.gp_etablissement = e.et_etablissement
    where
        -- simple to get all records for past 13 months for now just to 
        -- show summary, or change to 24 months as so needed
        p.gp_DatePiece > dateadd( month, -13, getdate())
    group by
        p.gp_etablissement,
        e.et_libelle,
        CONVERT(CHAR(7),GETDATE(),120)

以上结果可能类似于...

gp_etablissement  et_libelle   YrMonth   MonthsPrior   SumPerEtabliss
establissID1      libell1      2018-12   4             382
establissID1      libell1      2019-01   3             123
establissID1      libell1      2019-02   2             821
establissID1      libell1      2019-03   1             467

establissID2      libell2      2018-12   4             532
establissID2      libell2      2019-01   3             221
establissID2      libell2      2019-02   2             629
establissID2      libell2      2019-03   1             395

现在,您可以构建一个跨表查询,根据距原始月份有多少个月的时间来汇总各列。由于您需要24个月的时间,因此您必须复制/粘贴下面的sum()值以表示剩余的列。

select
        pq.gp_etablissement,
        pq.et_libelle,
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 1 then 1 else 0 end ) as [Month 1],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 2 then 1 else 0 end ) as [Month 2],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 3 then 1 else 0 end ) as [Month 3],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 4 then 1 else 0 end ) as [Month 4],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 5 then 1 else 0 end ) as [Month 5],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 6 then 1 else 0 end ) as [Month 6],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 7 then 1 else 0 end ) as [Month 7],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 8 then 1 else 0 end ) as [Month 8],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 9 then 1 else 0 end ) as [Month 9],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 10 then 1 else 0 end ) as [Month 10],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 11 then 1 else 0 end ) as [Month 11],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 12 then 1 else 0 end ) as [Month 12],
        sum( pq.SumPerEtabliss * case when pq.MonthsPrior = 13 then 1 else 0 end ) as [Month 13]
    from
        ( THE ENTIRE QUERY ABOVE THAT DOES THE GROUP BY ) PQ
    group by
        pq.gp_etablissement,
        pq.et_libelle
    order by
        pq.et_libelle