Оптимизация запросов (автоматическая нумерация)

#sql #sql-server #count #subquery #inner-join

#sql #sql-сервер #количество #подзапрос #внутреннее соединение

Вопрос:

У меня есть эти две таблицы (упрощенные), могут содержать много назначений и много эпизодов

Назначение

 date       | person_id | episode_id  
----------- ----------- ------------
12-11-2019 |    1      |    1
18-10-2019 |    1      |    1
11-10-2019 |    1      |    1
10-12-2018 |    1      |    2
10-11-2018 |    1      |    2
  

Эпизоды

 episode_id | Name
----------- ------------
    1      | Episode 1
    2      | Episode 2
  

Теперь мне нужно указать номер встречи (в последовательности) внутри эпизода.

Таким образом, результат запроса будет:

 Appointment | Episode    | Appointment number
------------ ------------ ----------------------
12-11-2019  | Episode 1  |     3
18-10-2019  | Episode 1  |     2
11-10-2019  | Episode 1  |     1
10-12-2018  | Episode 2  |     2
10-11-2018  | Episode 2  |     1
  

Итак, мой запрос (упрощенный) выглядит следующим образом:

 select 
    a.date, e.name, 
    (select count(*) from appointment a1 
     where a1.espisode_id = a.episode_id and a1.date < a.date )   1 
From 
    appointment a 
join 
    episode e on e.episode_id = a.episode_id 
where 
    a.person_id = 1
  

Теперь это работает нормально, но оператор sub select уничтожает базу данных. У нас более 5 миллионов встреч и более миллиона эпизодов.

Есть идеи, как это оптимизировать, чтобы уменьшить нагрузку на базу данных?

Ответ №1:

Используйте оконные функции!

 select a.date, e.name, 
    row_number() over(partition by a.episode_id order by a.date) as appointment_number
from appointment a 
inner join episode e on e.episode_id = a.episode_id 
where a.person_id = 1