Оптимизация запросов - занимает так много времени - PullRequest
0 голосов
/ 27 апреля 2019

У меня есть этот запрос, который показывает оборот за предыдущие 24 месяца до текущей даты.

Я использую SQL SERVER 2008, моя проблема в том, что мой запрос выполняется так долго.

Я использую 2 таблицы: Etablissement, чтобы получить название магазина, и кусок, чтобы получить сумму оборота каждого etablissement. результат: введите описание изображения здесь

select ETAB.ET_ETABLISSEMENT as 'STORE CODE'

[Month-1]=(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),

    [Month-2]=(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),

    [Some thing for the other months ..]
    [Month-24]..,

    from ETABLISS ETAB

Есть ли решение, пожалуйста, чтобы оптимизировать мой запрос?

Ответы [ 3 ]

0 голосов
/ 27 апреля 2019

Для каждой записи, выполняемой этими двумя функциями, year(DATEADD(MONTH,-1,GETDATE())) и MONTH( DATEADD(MONTH,-1,GETDATE())), она всегда дает постоянное значение, сохраняет эти значения в переменной и использует эти переменные в запросе, чтобы повысить скорость.

0 голосов
/ 27 апреля 2019

Ваш запрос, как написано, довольно запутанный, и, вероятно, почему только один другой даже предложил решение.Теперь давайте попробуем упростить и уточнить, что вы просите.Поправьте меня, если что-то не так.

Вам нужен запрос, который показывает итоги за последние 13 месяцев, сгруппированные по каждому коду магазина.Первый месяц представляет месяц, предшествующий текущему и возвращающийся на 13 месяцев назад (или 24, как вы указали).

Теперь ваш запрос.Вы запрашиваете из своей таблицы ETABLISS и группируете по gp_etablisssement, et_libelle.
Делая гугл-перевод с французского на английский

Etablissement = Establishement
Libelle = Wording

Так что я УДОБСТВУЮ, что ваш etablissement - это скорее ключ ID, которыйуникальный и Libelle - это метка, которая будет показана для данного etablissement.

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

Таким образом, метка всегда будет иметь прямую корреляцию с полем etablissement (ID).

Давайте сначала упростим,Вы хотите получить сумму всех основных значений, которые соответствуют критериям для некоторых фильтров.Начните с этого, и таблица фигур является основой критериев диапазона дат.Таблица Piece содержит поле etablissement, которое вы в конечном итоге хотите сгруппировать по

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 ().Это поможет вашему сводному результату вытягивать все данные в одну строку для каждого etablissement.

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
0 голосов
/ 27 апреля 2019

Это комментарий, который не помещается в разделе комментариев.

Я понял, что у вас несколько запросов, и они становятся медленными.Давайте по одному.Например:

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

Прежде всего, для его оптимизации нам важно знать, откуда идет каждый столбец.Итак ... пожалуйста добавьте префикс для всех столбцов, которые вы упоминаете.Мы не можем угадать таблицы для каждого столбца.

...