как вытащить первые 10 записей?

 
0
 
Oracle
ava
guest | 27.05.2005, 17:50
Помогите с запросом .Надо вытащить первые 10 записей.

Comments (14)
ava
LSD | 27.05.2005, 17:39 #
select * from (select t.*, t.rownum from table t order by field1) where rownum<=N
ava
Kurt | 29.05.2005, 23:15 #
LSD
А нет че-нить более оптимального?
Как я понимаю, тут сначала делается запрос на выборку ВСЕХ данных из таблицы, а уж потом берутся первые 10 строк из полученного резалтсета.
А если исходначя таблица будет большой, а нам нужны жалкие 10 строчек? Ведь получается излишняя нагрузка на сервер?
ava
&lt;Spawn&gt; | 30.05.2005, 05:08 #
Kurt Смотри мой пример
ava
Kurt | 30.05.2005, 13:01 #
<Spawn>
Так это ж то же самое, что и пример LSD..
Точно так же сначала делается выборка ВСЕХ строк.
ava
stron | 30.05.2005, 14:09 #
Kurt
А я себе другого варианта не представляю.
У тебя же есть условие where, поэтому тебе всё равно придётся бежать по всей таблице.
Причём этого не избежать, даже если использовать курсоры

Я бы вытаскивал записи так(Oracle не знаю, поэтому пишу под MsSQL):

DECLARE @Name varchar(40)
DECLARE CT CURSOR FOR SELECT t1_data from t1 where t1_id > 8
OPEN CT
Declare @i int
set @i = 0
WHILE @i<10 
BEGIN
  FETCH FROM CT INTO @Name  
  set @i = @i + 1 
  print @Name
END
DEALLOCATE CT


А в Oracle есть аналоги LIMIT в MySQL? Если есть, так это надо использовать
ava
LSD | 30.05.2005, 19:57 #
Цитата (Kurt @ 30.5.2005, 00:15)
LSD

А нет че-нить более оптимального?

Я ступил, тот запрос вообще работать будет некоректно, надо так:
select * 
from ( select a.*, rownum rnum
from ( YOUR_QUERY_GOES_HERE, including the order by ) a
where rownum <= MAX_ROWS )
where rnum >= MIN_ROWS
/

Этот запрос вернет строки с MIN_ROWS по MAX_ROWS. Рекомендую посмотреть getting rows N through M of a result set.
ava
Kurt | 30.05.2005, 23:02 #
Цитата (LSD)
Я ступил, тот запрос вообще работать будет некоректно

Бывает:
Цитата (LSD)
--------------------

Каждый человек имеет право на "немного потупить".

smile

Но я все равно не совсем понимаю. Вот у меня есть таблица, скажем, на 4GB. Чтоб вытащить первые 10 строчек, я все равно сначала тяну всю таблицу? :omg
Ведь в вышеописанных примерах сначала делается "общий запрос" (достать все данные), а уж потом из него выдергиваются нужные 10 строчек.
Неужели в такой крутой и общепризнанной базе нет такой очень полезной штуки?
Неужели нет аналога MySQL'евского LIMIT или Cache'йного TOP?
ava
&lt;Spawn&gt; | 31.05.2005, 05:03 #
Есть одна идея, но не знаю на сколько она реальна (и проверить нет возможности - на работе Oracle 8, дома 9-ка пока не стоит smile ) - насколько я помню, то есть функции итерпретации коллекции в виде таблицы, тогда тебе нужно будет написать функцию, возвращающую коллекцию записей(а на PL\SQL ты сам можешь на нужном fetch-е остановить выборку) и потом ее интерпретировать как таблицу в from части селекта.
ava
LSD | 31.05.2005, 20:16 #
Цитата (Kurt @ 31.5.2005, 00:02)
Но я все равно не совсем понимаю. Вот у меня есть таблица, скажем, на 4GB. Чтоб вытащить первые 10 строчек, я все равно сначала тяну всю таблицу?

Давайте не будем путать тянуть всю таблицу и просматривать всю таблицу. Во первых клиент получит только первые N записей, а во вторых какими порциями fetch-ить данные зависит от клиента и способа доступа к данным (в Java данные в ResultSet можно подкачивать по частям).
По поводу полного просмотра таблицы, если в подзапросе используется order by, то просмотра таблицы не избежать никак. Если поле не индексированное, то просмотр будет полным, если индексированное то будет полный просмотр индекса (во всяком случае такой план я получил на тестовой табличке). Стоимость запроса с order by по первичному ключу и по нениндексированному полю, различается в 3-4 раза.

Если же порядок не важен то можно использовать:
select * from my_table where rownum <= MAX_ROWS

И полного просмотра не будет.
added later:
По поводу идеи <Spawn>, она реализуема. Но я не думаю, что открытие курсора по внутреннему запросу и fetch, будет быстрее, чем прямой SQL запрос на первые N строк. Хотя надо попробовать.
ava
Stampede | 31.05.2005, 20:58 #
Цитата (Kurt @ 30.5.2005, 23:02)
Но я все равно не совсем понимаю. Вот у меня есть таблица, скажем, на 4GB. Чтоб вытащить первые 10 строчек, я все равно сначала тяну всю таблицу?


Не все так плохо. Оптимизатор оракла понимает, что мы хотим отсечь часть результатов, и строит план выполнения запроса таким образом, чтобы поскорее от нас отделаться smile Проверял неоднократно на различный типах запросов, в том числе с большими объемами данных. Работает нормально.

А то, что синтаксис получается неудобный - это да, есть такое дело. Более того, до версии 8i такая конструкция вообще была неозможна - оракл ругался на ORDER BY в подзапросе. В результате получалось, что мы только можем взять первые N записей (в каком уж там порядке они придут зависит от типа запроса), и уже внутри них отсортировать по нужному нам полю - что, разумеется, было не совсем то, что мы хотели получить.

Но только не надо на этом основании говорить, что оракыл сакс (хотя он, конечно, сакс). Просто у каждой СУБД есть свои тараканы. А что делать? Нет в мире совершенства :)

ava
rmaf | 20.07.2005, 12:05 #
Почитав ваши мнения, решил попробовать с этого:

select * from (select t.*, rownum from MONITOR t order by DATE_OPER) where rownum<=10

сделать это:

select t.*, rownum from MONITOR t where rownum<=10

результат одинаковый.

"Так зачем платить больше?"

или я чего-то не понимию?
ava
LSD | 20.07.2005, 13:18 #
Цитата (rmaf @ 20.7.2005, 13:05)
результат одинаковый.



"Так зачем платить больше?"



или я чего-то не понимию?

Результат будет разный, в первом случае вначале записи будут отсортированны, а только затем выбранны первые 10 строк. А во втором слечае вначале будут отобранны первые 10 строк (какие они будут неизвестно), а затем они будут отсортированны.

P.S. Для кода есть кнопочка "Код", используй ее, так код будет более читабельным.
ava
rmaf | 20.07.2005, 14:03 #
Спасибо за пояснения...
added later:
LSD а можно ли как-то запросом узнать сколько и какие столбцы в таблице?
Это я так, под руку спрашиваю, вдруг ты знаешь...
ava
LSD | 20.07.2005, 17:04 #
Цитата (rmaf @ 20.7.2005, 15:03)
LSD а можно ли как-то запросом узнать сколько и какие столбцы в таблице?

select * from all_tab_columns where owner = 'SYS' and table_name = 'DUAL'


Цитата (rmaf @ 20.7.2005, 15:03)
Это я так, под руку спрашиваю, вдруг ты знаешь...

По правилам форума:
Цитата
10) Запрещается создание сообщения с несколькими вопросами. На каждый вопрос должна создаваться отдельная тема. В случае возникновения таких тем, администрация форума оставляет за собой право изменить текст сообщения, удалить его или закрыть тему.

Если вопрос большой, лучше создать отдельную тему, а если вопрос маленький и была связанная тема, то лучше спросить в ней. В твоем случае здесь. А то придут модераторы и будут ругаться smile
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
  guest   &lt;Spawn&gt;   stron   Kurt ava  LSD   Stampede   rmaf
advanced
Submit