Чтобы запросить top-n строк в Oracle, обычно используется ROWNUM. Так что следующий запрос кажется нормально (получает 5 последних платежей):Производительность Oracle ROWNUM
select a.paydate, a.amount
from (
select t.paydate, t.amount
from payments t
where t.some_id = id
order by t.paydate desc
) a
where rownum <= 5;
Но для очень больших таблиц, это неэффективно - для меня это работать в течение ~ 10 минут. Так что я пробовал другие вопросы, и я закончил с этим, который работает меньше, чем вторая:
select *
from (
select a.*, rownum
from (select t.paydate, t.amount
from payments t
where t.some_id = id
order by t.paydate desc) a
)
where rownum <= 5;
Чтобы выяснить, что происходит, я смотрел планы выполнения для каждого запроса. Для первого запроса:
SELECT STATEMENT, GOAL = ALL_ROWS 7 5 175
COUNT STOPKEY
VIEW 7 5 175
TABLE ACCESS BY INDEX ROWID 7 316576866 6331537320
INDEX FULL SCAN DESCENDING 4 6
И для второй:
SELECT STATEMENT, GOAL = ALL_ROWS 86 5 175
COUNT STOPKEY
VIEW 86 81 2835
COUNT
VIEW 86 81 1782
SORT ORDER BY 86 81 1620
TABLE ACCESS BY INDEX ROWID 85 81 1620
INDEX RANGE SCAN 4 81
Очевидно, что это INDEX FULL SCAN DESCENDING, что делает первый запрос неэффективную для больших таблиц. Но я не могу отличить логику двух запросов, глядя на них. Может ли кто-нибудь объяснить мне логические различия между двумя запросами на человеческом языке?
Заранее благодарен!
id - переменная связывания, нет (должно быть: id?), Если да, какое значение используется (такое же?) – tbone
Я не думаю, что 'rownum', который вы используете для фильтра во второй версии, гарантированно будет таким же, как и в первом; подумайте, что вам нужно либо добавить свой второй запрос и ссылку, либо добавить в запрос запрос 'order by rownum' против' a'? Я сомневаюсь, что это влияет на скорость. –