Порядок строк по умолчанию для запроса выбора в оракуле

Каков порядок строк в Oracle по умолчанию для запроса на выборку, если не указано условие «order by».

Is it

  1. порядок вставки строк
  2. вообще нет порядка по умолчанию
  3. ни один из вышеперечисленных.

person sengs    schedule 22.05.2009    source источник
comment
Этот вопрос часто задают (я видел, как он поднимался на нескольких форумах). Я думаю, это может быть вызвано ложным убеждением, что ORDER BY заставит CBO выполнить сортировку, которая, очевидно, дороже, чем выполнение неупорядоченного запроса. Существуют способы улучшить производительность сортировки в Oracle, но они не требуют отказа от предложения ORDER BY.   -  person Jeffrey Kemp    schedule 26.05.2009
comment
Уже есть достаточно ответов, чтобы подчеркнуть, но просто добавить - без явного порядка механизм выполнения будет возвращать строки по мере их извлечения из хранилища. Способ выборки строк зависит от плана выполнения. План выполнения может измениться, особенно с версии 11g с адаптивными функциями, такими как обратная связь со статистикой. Строки хранятся в блоках, последовательность которых не гарантируется.   -  person William Robertson    schedule 02.06.2019


Ответы (8)


По словам Тома Кайта: «До тех пор, пока вы не добавите в запрос «упорядочить по», вы не сможете НИЧЕГО сказать о порядке возвращаемых строк. Ну, за исключением «вы не можете полагаться на порядок возвращаемых строк».

См. этот вопрос по адресу asktom.com.

Что касается ROWNUM, то его физически не существует, поэтому его нельзя «освободить». ROWNUM присваивается после извлечения записи из таблицы, поэтому «WHERE ROWNUM = 5» всегда не сможет выбрать какие-либо записи.

@ammoQ: вы можете прочитать эту статью AskTom о групповом заказе. Короче:

Гарантирует ли предложение Group By в запросе, что выходные данные будут отсортированы по столбцам Group By по порядку, даже если нет предложения Order By?

и мы сказали...

ТОЧНО НЕТ,

Такого никогда не было, никогда не было и никогда не будет.

person DCookie    schedule 22.05.2009
comment
Спасибо, я знаю эту статью. 2 года назад очень внимательно изучил его, буквально проведя недели с вопросом: Почему эта прога ведет себя иначе на 10g? - person Erich Kitzmueller; 23.05.2009
comment
Проще говоря, потому что Oracle делает что-то по-другому в 10g. Однако это не ошибка в Oracle! Oracle НИКОГДА не использовал GROUP BY для сортировки результатов, и Том показывает, как это может привести к сбою в 9i. Просто потому, что так часто казалось, люди полагались на это. Эта статья, помимо информативности, является одной из самых удивительных иллюстраций того, как люди не могут или не хотят принять простую концепцию, потому что она отличается от их собственных анекдотических наблюдений. Это также довольно забавно. ЕСЛИ ВЫ ХОТИТЕ СОРТИРОВАТЬ ВАШИ ДАННЫЕ, ИСПОЛЬЗУЙТЕ ORDER BY. - person DCookie; 23.05.2009
comment
@DCookie это поведение ограничено Oracle или оно применимо ко всем реляционным базам данных, таким как MySQL, Postgres? - person Narendra Jaggi; 09.04.2016
comment
@NarendraJaggi: это верно для всех реляционных баз данных. - person a_horse_with_no_name; 20.07.2016
comment
@DCookie: Спасибо, что объяснили в двух словах. - person Amey; 30.12.2017
comment
8 лет, и это все еще помогает ответить на вопрос, почему возникают определенные ошибки. спасибо, что поделились статьями! - person Steven Ferrer; 15.08.2018

Нет явного порядка по умолчанию. По понятным причинам, если вы создадите новую таблицу, вставите несколько строк и сделаете «выбрать *» без предложения «где», она (весьма вероятно) вернет строки в том порядке, в котором они были вставлены.

Но вы никогда не должны полагаться на порядок по умолчанию. Если вам нужен конкретный порядок, используйте пункт «заказ по». Например, в версиях Oracle до 9i выполнение «группировки по» также приводило к сортировке строк по групповому выражению. В 10g такого поведения больше нет! Из-за этого обновление установок Oracle заставило меня потрудиться.

person Erich Kitzmueller    schedule 22.05.2009
comment
Да к ответу, но к придиркам: на самом деле не так очевидно - нет гарантии, что новые строки будут вставлены в новую таблицу в любом конкретном порядке, и нет гарантии, что SELECT без ORDER BY обязательно посетит все блоки в таблице. таблицы в том же порядке, в котором они были созданы. - person Jeffrey Kemp; 25.05.2009
comment
Да, гарантии как таковой нет. Но мне было бы трудно создать сценарий, в котором это не работает. - person Erich Kitzmueller; 25.05.2009
comment
Если вы создаете таблицу со 100 записями, удаляете первые 50, а затем вставляете еще 10, Oracle будет стремиться повторно использовать пространство из удаленных строк (с учетом множества «если», «но» и т. д.). Таким образом, даже если Oracle посещает блоки в том же порядке, последние 10 вставленных записей будут иметь тенденцию быть первыми в запросе без ORDER BY. - person Sten Vesterli; 27.05.2009
comment
Четко. Вот почему его пример был if you create a **new** table, insert a few rows and do a select Хотя я бы сказал ...it will _most likely_ return... - person Amit Naidu; 16.04.2013

Уже было сказано, что Oracle может предоставить вам строки в любом порядке, который он хочет, если вы не укажете предложение ORDER BY. Предполагать, каким будет порядок, если вы не укажете предложение ORDER BY, бессмысленно. И полагаться на это в вашем коде - это "шаг, ограничивающий карьеру".

Простой пример:

SQL> create table t as select level id from dual connect by level <= 10
  2  /

Tabel is aangemaakt.

SQL> select id from t
  2  /

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 rijen zijn geselecteerd.

SQL> delete t where id = 6
  2  /

1 rij is verwijderd.

SQL> insert into t values (6)
  2  /

1 rij is aangemaakt.

SQL> select id from t
  2  /

        ID
----------
         1
         2
         3
         4
         5
         7
         8
         9
        10
         6

10 rijen zijn geselecteerd.

И это только после простого удаления+вставки. И есть множество других мыслимых ситуаций. Параллельное выполнение, разделы, таблицы, организованные по индексу, и это лишь некоторые из них.

Итог, как уже очень хорошо сказал ammoQ: если вам нужно отсортировать строки, используйте предложение ORDER BY.

person Rob van Wijk    schedule 23.05.2009
comment
+1 за ограничение карьеры, основанное на упорядочении неупорядоченных запросов. - person Ollie; 26.10.2011
comment
Спасибо за ссылку. Собственно, оттуда я и взял эту цитату. - person Rob van Wijk; 17.04.2013
comment
что, если я никогда не удалю и не вставлю? Я воссоздаю таблицу с нуля как select * from another_table order by filed1 - person Toolkit; 18.10.2017

Вы абсолютно точно не можете полагаться на какой-либо порядок, если не укажете order by. В частности, для Oracle я действительно видел точно такой же запрос (без соединений), запускаемый дважды с интервалом в несколько секунд друг от друга, в таблице, которая не изменилась за это время, возвращая совершенно другой порядок. Это кажется более вероятным, когда набор результатов большой.

Параллельное исполнение, упомянутое Робом ван Вейком, вероятно, объясняет это. См. также документ Oracle Использование параллельного выполнения.

person Kelvin    schedule 26.03.2013

На него влияет индекс, если есть индекс, он вернет порядок по возрастанию, если индекса нет, он вернет вставленный порядок.

person Amir Buzo    schedule 05.11.2016

Вы можете изменить порядок, в котором данные сохраняются в таблице, с помощью INSERT с предложением ORGANIZATION оператора CREATE TABLE.

person d0dulk0    schedule 29.11.2017
comment
Эм, не совсем. ORGANIZATION ничего не делает для таблиц кучи (по умолчанию). Это применимо только к таблицам organization indexed и external, которые имеют особое использование. Подробнее - person APC; 01.06.2019

Хотя это должен быть rownnum (ваш номер 2), на самом деле это не гарантировано, и вы не должны доверять ему на 100%.

person Ricardo Villamil    schedule 22.05.2009
comment
rownum сообщает порядок, в котором возвращаются строки; это не поможет вам с порядком, в котором они должны быть возвращены. - person Jonathan Leffler; 23.05.2009

Я считаю, что он использует скрытый атрибут Oracle Rownum.

Таким образом, ваш № 1, вероятно, прав, предполагая, что не было выполнено никаких удалений, которые могли бы освободить ряды для последующего использования.

EDIT: Как уже говорили другие, вам никогда не следует полагаться на это. Помимо удаления, существует множество различных условий, которые могут повлиять на поведение сортировки по умолчанию.

person Zenshai    schedule 22.05.2009
comment
ROWNUM не является атрибутом, а назначается только при запросе. ROWID также не является атрибутом — он просто выражает файл, блок и строку как одно значение. Он сохраняется в индексах как указатель на реальную строку. - person Gary Myers; 23.05.2009