На этот вопрос довольно сложно ответить без дополнительной информации о данных и таблице. Когда вы говорите в своем комментарии, что у вас есть все нужные вам индексы, что это за индексы?
Кроме того, периоды времени примыкают и не перекрываются? Вы можете просто получить период с самой последней START_DATE?
Проблема с просмотром END_DATE состоит в том, что обычный индекс B-Tree не индексирует NULL. Таким образом, предикат вида where end_date is nulll
вряд ли будет использовать индекс. Вы можете использовать растровый индекс со столбцом, так как индексы этого типа делают индекс пустыми, но это может быть не идеальным из-за некоторых других недостатков растровых индексов.
По причинам, указанным выше, я бы, вероятно, использовал запрос, подобный приведенному ниже:
select user, plan, start_date, end_date
from (
select
user,
plan,
start_date,
end_date,
row_number() over (partition by user order start_date desc) as row_num_1,
row_number() over (partition by user order end_date desc nulls first) as row_num_2
from user_table
where user = :userid
)
where row_num_1 = 1
Возможно, вы можете использовать столбец row_num_1
или row_num_2
здесь, в зависимости от точных требований.
OR
select user, plan, start_date, end_date
from (
select
user,
plan,
start_date,
end_date,
from user_table
where user = :userid
order by start_date desc
)
where rownum = 1
Первый запрос должен работать независимо от того, пытаетесь ли вы вернуть всех пользователей или только одного. Второй запрос будет работать только с одним пользователем.
Если вы можете дополнить вопрос более подробной информацией о схеме (указатели, значения даты начала / окончания), вы, вероятно, получите лучшие ответы.