Oracle - Можно ли оптимизировать этот запрос? - PullRequest
0 голосов
/ 19 октября 2018

Я хочу получить последнюю дату набора строк.Что является более производительным: Query1 или Query2:

Query1

select *
from(
select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234'
order by column_date desc) c
where rownum=1

Query2

select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234'
order by column_date desc

и возьмитепервый ряд в бэкенде.

Или, может быть, есть другой способ получить первый ряд в Oracle?Я знаю, что обычно подвыборы плохо работают.Вот почему я пытаюсь удалить подвыбор.

Я пробовал это, но я не получаю ожидаемый результат:

select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234' and rownum=1
order by column_date desc

1 Ответ

0 голосов
/ 21 октября 2018

Во-первых, вы не можете оптимизировать запрос .Запросы всегда переписываются оптимизатором и могут давать очень разные результаты в зависимости от объема данных, индексов и т. Д. Поэтому, если у вас медленный запрос, вы должны посмотреть на план выполнения, чтобы увидеть, что происходит.И если у вас есть запрос, который не является медленным, вы не должны его оптимизировать.

Нет ничего плохого в подселектах как таковых.Как предполагает Wernfriend Domscheit, это даст вам минимальную дату column_date, которая, как я полагаю, находится в таблице 2.

SELECT MIN( b.column_date ) 
  FROM table1 a 
 INNER JOIN table2 b on a.column1 = b.column1 
 WHERE a.id= '1234'

Это гарантированно даст вам одну строку.Если вам нужно больше, чем просто поле даты, будут выбраны строки с минимальной датой:

 SELECT a.*, b.column_date
  FROM table1 a 
 INNER JOIN table2 b on a.column1 = b.column1 
 WHERE a.id= '1234'
   AND b.column_date = ( SELECT MIN( b2.column_date ) FROM table2 b2 )

Но если ваша column_date не уникальна, это может вернуть несколько строк.Если это возможно, вам нужно что-то в данных, чтобы дифференцировать строки для выбора.Это гарантированно даст вам одну строку:

SELECT * FROM (
     SELECT a.*, b.column_date
      FROM table1 a 
     INNER JOIN table2 b on a.column1 = b.column1 
     WHERE a.id= '1234'
       AND b.column_date = ( SELECT MIN( b2.column_date ) FROM table2 b2 )
     ORDER BY a.some_other_column 
)
WHERE ROWNUM = 1

В достаточно недавней версии Oracle вы можете использовать FETCH FIRST 1 ROW ONLY вместо ROWNUM запроса.Я не думаю, что это имеет значение.

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