Ускорьте время выполнения запроса с помощью нескольких выражений case когда - PullRequest
1 голос
/ 22 сентября 2019

У меня есть следующий код ниже.Это простая сумма с особыми условиями и деленная на счет отличная функция с особыми условиями.Проблема, которая занимает слишком много времени, чтобы бежать.Сейчас 2 дня, и он еще не закончился.Как я могу сделать это быстрее?Это часть кода, когда дело повторяется более 100 раз, так как я отслеживаю каждый месяц.

Select 

 (sum (case when INSTALLATION_TYPE like'%R' and RATE_FAKT = 'VI' and INvoice_Date between '2018-01-01' and '2018-12-31' then QUANT end)/1000)/

Count (Distinct (case when INSTALLATION_TYPE like'%R' and RATE_FAKT = 'VI' and INvoice_Date between '2018-01-01' and '2018-12-31' then MIRN end) )CY18_GJPERMIRN_VI,



(sum (case when RATE_FAKT = 'VB' and INvoice_Date between '2018-01-01' and '2018-12-31' then QUANT end)/1000)/

Count (Distinct (case when INSTALLATION_TYPE like'%R' and RATE_FAKT = 'VB' and INvoice_Date between '2018-01-01' and '2018-12-31' then MIRN end) )CY18_GJPERMIRN_VB,



  (sum (case when INSTALLATION_TYPE like'%B' and RATE_FAKT = 'VI' and INvoice_Date between '2018-01-01' and '2018-12-31' then QUANT end)/1000)/

Count (Distinct (case when INSTALLATION_TYPE like'%B' and RATE_FAKT = 'VI' and INvoice_Date between '2018-01-01' and '2019-12-31' then MIRN end) )CY18_GJPERMIRN_VI_Commercial,


  (sum (case when INSTALLATION_TYPE like'%R' and RATE_FAKT = 'VI' and INvoice_Date between '2019-01-01' and '2019-08-31' then QUANT end)/1000)/

Count (Distinct (case when INSTALLATION_TYPE like'%R' and RATE_FAKT = 'VI' and INvoice_Date between '2019-01-01' and '2019-08-31' then MIRN end) )CY19_AUG_GJPERMIRN_VI,


(sum (case when RATE_FAKT = 'VB' and INvoice_Date between '2019-01-01' and '2019-08-31' then QUANT end)/1000)/

Count (Distinct (case when INSTALLATION_TYPE like'%R' and RATE_FAKT = 'VB' and INvoice_Date between '2019-01-01' and '2019-08-31' then MIRN end) )CY19_AUG_GJPERMIRN_VB,


  (sum (case when INSTALLATION_TYPE like'%B' and RATE_FAKT = 'VI' and INvoice_Date between '2019-01-01' and '2019-08-31' then QUANT end)/1000)/


Count (Distinct (case when INSTALLATION_TYPE like'%B' and RATE_FAKT = 'VI' and INvoice_Date between '2019-01-01' and '2019-08-31' then MIRN end) )CY19_AUG_GJPERMIRN_VI_Commercial

  FROM [Analytics_JGN].[dbo].[VW_BILLINGS]


  Where MIRN like '524%';

Ответы [ 3 ]

1 голос
/ 22 сентября 2019

Вам необходимо использовать dynamic PIVOT запрос, чтобы генерировать столбцы динамически .Эта ссылка поможет вам в этом.Поскольку я проверил, что есть 3 столбца (GJPERMIRN_VI, GJPERMIRN_VB, GJPERMIRN_VI_Commercial), повторяющихся по годам, и префикс CY(Last 2 character of year from Invoice date column)_.

, я изменил ваш запрос с оператора CASE на UNION ALL с CTE.Это будет немного быстрее.Пожалуйста, проверьте ниже ответ на ваш запрос.

;WITH CTE_GJPERMIRN
AS
(
    SELECT
        (SUM(ISNULL(QUANT,0)) / 1000) / ISNULL(COUNT(DISTINCT MIRN),1) AS CY18_GJPERMIRN_VI,
        0 AS CY18_GJPERMIRN_VB,
        0 AS CY18_GJPERMIRN_VI_Commercial,
        0 AS CY19_AUG_GJPERMIRN_VI,
        0 AS CY19_AUG_GJPERMIRN_VB,
        0 AS CY19_AUG_GJPERMIRN_VI_Commercial
    FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
    Where MIRN LIKE '524%'
    AND INSTALLATION_TYPE LIKE '%R' 
    AND RATE_FAKT = 'VI' 
    AND INvoice_Date BETWEEN '2018-01-01' AND '2018-12-31'

    UNION ALL

    SELECT
        0 AS CY18_GJPERMIRN_VI,
        (SUM(ISNULL(QUANT,0)) / 1000) / ISNULL(COUNT(DISTINCT MIRN),1) AS CY18_GJPERMIRN_VB,
        0 AS CY18_GJPERMIRN_VI_Commercial,
        0 AS CY19_AUG_GJPERMIRN_VI,
        0 AS CY19_AUG_GJPERMIRN_VB,
        0 AS CY19_AUG_GJPERMIRN_VI_Commercial
    FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
    Where MIRN LIKE '524%'
    AND INSTALLATION_TYPE LIKE '%R'
    AND RATE_FAKT = 'VB' 
    AND INvoice_Date BETWEEN '2018-01-01' AND '2018-12-31'

    UNION ALL

    SELECT
        0 AS CY18_GJPERMIRN_VI,
        0 AS CY18_GJPERMIRN_VB,
        (SUM(ISNULL(QUANT,0)) / 1000) / ISNULL(COUNT(DISTINCT MIRN),1) AS CY18_GJPERMIRN_VI_Commercial,
        0 AS CY19_AUG_GJPERMIRN_VI,
        0 AS CY19_AUG_GJPERMIRN_VB,
        0 AS CY19_AUG_GJPERMIRN_VI_Commercial
    FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
    Where MIRN LIKE '524%'
    AND INSTALLATION_TYPE LIKE '%B' 
    AND RATE_FAKT = 'VI' 
    AND INvoice_Date BETWEEN '2018-01-01' AND '2018-12-31' --Consider 2018 year in End Date instead of 2019 in count distinct case statement

    UNION ALL

    SELECT
        0 AS CY18_GJPERMIRN_VI,
        0 AS CY18_GJPERMIRN_VB,
        0 AS CY18_GJPERMIRN_VI_Commercial,
        (SUM(ISNULL(QUANT,0)) / 1000) / ISNULL(COUNT(DISTINCT MIRN),1) AS CY19_AUG_GJPERMIRN_VI,
        0 AS CY19_AUG_GJPERMIRN_VB,
        0 AS CY19_AUG_GJPERMIRN_VI_Commercial
    FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
    Where MIRN LIKE '524%'
    AND INSTALLATION_TYPE LIKE'%R' 
    AND RATE_FAKT = 'VI' 
    AND INvoice_Date BETWEEN '2019-01-01' AND '2019-08-31'

    UNION ALL

    SELECT
        0 AS CY18_GJPERMIRN_VI,
        0 AS CY18_GJPERMIRN_VB,
        0 AS CY18_GJPERMIRN_VI_Commercial,
        0 AS CY19_AUG_GJPERMIRN_VI,
        (SUM(ISNULL(QUANT,0)) / 1000) / ISNULL(COUNT(DISTINCT MIRN),1) AS CY19_AUG_GJPERMIRN_VB,
        0 AS CY19_AUG_GJPERMIRN_VI_Commercial
    FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
    Where MIRN LIKE '524%'
    AND INSTALLATION_TYPE LIKE '%R'
    AND RATE_FAKT = 'VB' 
    AND INvoice_Date BETWEEN '2019-01-01' AND '2019-08-31'

    UNION ALL

    SELECT
        0 AS CY18_GJPERMIRN_VI,
        0 AS CY18_GJPERMIRN_VB,
        0 AS CY18_GJPERMIRN_VI_Commercial,
        0 AS CY19_AUG_GJPERMIRN_VI,
        0 AS CY19_AUG_GJPERMIRN_VB,
        (SUM(ISNULL(QUANT,0)) / 1000) / ISNULL(COUNT(DISTINCT MIRN),1) AS CY19_AUG_GJPERMIRN_VI_Commercial
    FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
    Where MIRN LIKE '524%'
    AND INSTALLATION_TYPE LIKE '%B' 
    AND RATE_FAKT = 'VI' 
    AND INvoice_Date BETWEEN '2019-01-01' AND '2019-08-31'
)
SELECT
    SUM(CG.CY18_GJPERMIRN_VI)                AS CY18_GJPERMIRN_VI,
    SUM(CG.CY18_GJPERMIRN_VB)                AS CY18_GJPERMIRN_VB,
    SUM(CG.CY18_GJPERMIRN_VI_Commercial)     AS CY18_GJPERMIRN_VI_Commercial,
    SUM(CG.CY19_AUG_GJPERMIRN_VI)            AS CY19_AUG_GJPERMIRN_VI,
    SUM(CG.CY19_AUG_GJPERMIRN_VB)            AS CY19_AUG_GJPERMIRN_VB,
    SUM(CG.CY19_AUG_GJPERMIRN_VI_Commercial) AS CY19_AUG_GJPERMIRN_VI_Commercial
FROM CTE_GJPERMIRN CG

Примечание : CY18_GJPERMIRN_VI_Commercial - Вы можете указать неверную дату окончания в COUNT(DISTINCT) Ситуация с указанием даты выставления счета, которую я исправил.

0 голосов
/ 23 сентября 2019

Ваш запрос может быть optimized в 2-4 шага из-за проблем со связью.1. Сначала вы загружаете требуемые данные в таблицу Temp.2. Поскольку вы говорите, что это только часть кода, поэтому считаю мой сценарий также неполным.

CREATE TABLE #temp 
(
    INSTALLATION_TYPE VARCHAR(1),
    RATE_FAKT VARCHAR(2) ,
    INvoice_Date DATETIME,
    QUANT INT,
    MIRN INT
)

INSERT INTO #temp 
(
    INSTALLATION_TYPE,
    RATE_FAKT,
    INvoice_Date,
    QUANT,
    MIRN
) 
SELECT 
    RIGHT(INSTALLATION_TYPE,1),
    RATE_FAKT,
    INvoice_Date,
    QUANT,
    MIRN 
FROM [Analytics_JGN].[dbo].[VW_BILLINGS] 
WHERE INvoice_Date >= '2018-01-01' 
AND INvoice_Date <= '2019-12-31'

SELECT * FROM #temp

DROP TABLE #temp;
0 голосов
/ 22 сентября 2019

Для устранения неполадок производительности вы можете попробовать использовать множество отдельных операторов выбора вместо множества операторов в одном операторе выбора.Что-то вроде: (не проверено)

select *
from (
   Select sum(isnull(QUANT,0)/1000/Count(Distinct MIRN) CY18_GJPERMIRN_VI
   FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
   Where MIRN like '524%'
      and INSTALLATION_TYPE like'%R'
      and RATE_FAKT = 'VI'
      and INvoice_Date between '2018-01-01' and '2018-12-31'
) a
full outer join
(
   select sum(isnull(QUANT,0)/1000/Count(Distinct(MIRN) CY18_GJPERMIRN_VB
   FROM [Analytics_JGN].[dbo].[VW_BILLINGS]
   Where MIRN like '524%'
      and RATE_FAKT = 'VB'
      and INvoice_Date between '2018-01-01' and '2018-12-31'
) b on 1=1

Или другой подход заключается в использовании group by вместо операторов case - предполагая, что это разумно.Диапазоны дат по-прежнему должны быть заявлениями о регистре, но RATE_FAKT и INSTALLATION_TYPE, скорее всего, могут быть перемещены в GROUP BY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...