Фильтр подзапроса TSQL к проблеме производительности - PullRequest
0 голосов
/ 08 июля 2019

Я работаю над этим запросом. Когда я назначаю фильтр даты из подзапроса основному запросу, время ответа увеличивается с 1 секунды до 4,5 минут.

Я не знаю, как решить эту проблему и исправить мой запрос. Я пишу запрос и методы, которые я попробовал.

Спасибо за вашу помощь.

Мой запрос:

select
    START_DATE as DATE,
    [MINUTE] as MIN,
    map1.LT,
    ISNULL((SELECT
                (SELECT CAST((main.MIN) AS FLOAT)) /
                    (
            (nullif(
                (select cast(
                    (select 
                        sum(MIN2) 
                    from fooTable2 d2 
                        CROSS APPLY (select Top(1) LT from FooMap2 where x = d2.x) k2
                    where k2.LT = map1.LT
                        **-- PROBLEM CODE START**
                        and YEAR(d2.DATE) = YEAR(main.DATE) and MONTH(d2.DATE) = MONTH(main.DATE)
                        **-- PROBLEM CODE END**
                    ) as float)),0))
    as XX,
    ....... 

    ......
from Table1 main
OUTER APPLY (select Top(1) LT from FooMap where x = main.x) map1

Я попытался создать виртуальную таблицу.

Но не работает.

declare @child table ([Year] smallint, [Month] smallint, [Total] float,[LTCode] nvarchar(20))

insert into @child ([LTCode],[Year],[Month],[Total])
(select 
    k2.LT,YEAR(d2.DATE) as YIL,MONTH(d2.DATE) as AY,sum(MIN) as SURE
from DURUS d2 
    CROSS APPLY (select Top(1) LT from FooMap2 where x = d2.x) k2
group by k2.LT,YEAR(d2.DATE),MONTH(d2.DATE))
... 
    ....
(select [Total] from @child where [YEAR] = YEAR(main.DATE) and [MONTH] = MONTH(main.DATE) and [LTCode] = map1.LT)

Что мне делать?

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Основная проблема - модель данных.Вам нужно отфильтровать по месяцам и годам, но хранить данные в формате DATE, DATETIME или аналогичных. Нет простого способа сделать это быстро :

and YEAR(d2.DATE) = YEAR(main.DATE) 
and MONTH(d2.DATE) = MONTH(main.DATE)

ГДЕ ФУНКЦИЯ (Ввод) = ФУНКЦИЯ (Ввод) вызывает сканирование каждой таблицы, наличие двух таких фильтров означает, что вы касаетесь/ оценка каждого значения (d2.date и main.date) дважды для каждой строки в каждой таблице.Чтобы исправить это, вы можете выбрать следующие варианты:

  1. Добавление сохраняемого вычисляемого столбца в каждой таблице для года и месяца, а затем добавьте соответствующий индекс (по году, месяцу со всеми столбцами, задействованными в вашем запросе).как Включить столбцы.

  2. Используйте индексированное представление для предварительного объединения Durus и main, не просто, но выполнимо.

  3. Узнайте, как создавать ииспользуйте правильно проиндексированную таблицу календаря. Это потребует некоторых усилий, но также изменит вашу карьеру.

  4. Используйте другие фильтры на левой стороне ваших объединений ...
    Например:добавьте предложение WHERE после from fooTable2 d2, чтобы отфильтровать любые дополнительные строки перед объединением.

0 голосов
/ 08 июля 2019

Распространенные способы оптимизации: 1) убрать вычисления слева в фильтрах 2) отображать подзапросы в отдельных временных таблицах или в промежуточных запросах CTE 3) не используйте табличные переменные 4) на ранних этапах попытайтесь отфильтровать как можно больше данных перед подключением

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