Настройка SQL-запроса: подзапрос с агрегатной функцией в одной таблице - PullRequest
0 голосов
/ 07 мая 2018

Следующий запрос занимает около 30 секунд, чтобы дать результаты.table1 содержит ~ 20 м строк table2 содержит ~ 10000 строк

Я пытаюсь найти способ улучшить производительность.Есть идеи?

declare @PreviousMonthDate datetime 
select @PreviousMonthDate = (SELECT DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()) - 1, '19000101') as [PreviousMonthDate])

     select  
 distinct(t1.code), t1.ent, t3.lib, t3.typ from table1 t1, table2 t3
     where (select min(t2.dat) from table1 t2 where   t2.code=t1.code) >@PreviousMonthDate
and t1.ent in ('XXX')
and t1.code=t3.cod
and t1.dat>@PreviousMonthDate

Спасибо

1 Ответ

0 голосов
/ 07 мая 2018

Это ваш запрос, более разумно написано:

 select t1.code, t1.ent, t2.lib, t2.typ
 from table1 t1 join
      table2 t2
      on t1.code = t2.cod
 where not exists (select 1
                   from table1 tt1
                   where tt1.code = t1.code and
                         tt1.dat <= @PreviousMonthDate 
                  ) and
       t1.ent = 'XXX' and 
       t1.dat > @PreviousMonthDate;

Для этого запроса вы хотите следующие индексы:

  • table1(ent, dat, code) - для где
  • table1(code, dat) - для подзапроса
  • table2(cod, lib, typ) - для объединения

Примечания:

  • Псевдонимы таблицы должны составлятьсмысл.t3 для table2 является когнитивным диссонантом, хотя я знаю, что это выдуманные имена.
  • not exists (особенно с правильными индексами) должен быть быстрее, чем подзапрос агрегации.
  • Индексы будут удовлетворять условию where, сокращая объем данных, необходимых для фильтрации.
  • select distinct - это оператор.distinct не является функцией, поэтому круглые скобки ничего не делают.
  • Никогда не используйте запятую в предложении FROM. Всегда используйте правильный, явный, стандартный синтаксис JOIN.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...