powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Сохранение порядка строк в UNION ALL
25 сообщений из 51, страница 1 из 3
Сохранение порядка строк в UNION ALL
    #39997978
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня есть запрос в котором мне удобно сохранить порядок строк:

Код: plsql
1.
2.
3.
4.
5.
6.
select 'П' from dual   union all
select 'р' from dual   union all
select 'и' from dual   union all
select 'м' from dual   union all
select 'е' from dual   union all
select 'р' from dual 



По умолчанию, моя версия оракла уже так и делает - UNION ALL в 11.2 гарантирует последовательное исполнение подзапросов, и сохранение их порядка как они записаны сверху вниз.

В Оракле 12+ я знаю что можно указать хинт чтоб и там сохранялся порядок строк, но в ущерб параллельного исполнения подзапросов.

А как сделать чтобы и подзапросы исполнялись параллельно, и результат был в определенном порядке?
Параллельность важна, если у подзапросов долгий тайм-аут.

Пока я додумался до такого:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select val from (
  select 10, 'П' val from dual   union all
  select 20, 'р' from dual   union all
  select 30, 'и' from dual   union all
  select 40, 'м' from dual   union all
  select 50, 'е' from dual   union all
  select 60, 'р' from dual 
order by 1)



Что работает, немного коряво с точки зрения поддержки - нужно следить за номерами строк, как в старом бэйсике.

В PL/SQL 10.0+ очень удобно использовать $$PLSQL_LINE для этих целей, но в SQL это макро недоступно.

Есть ли способ решить эту задачу, кроме вышеописанной ручной нумерации строчек?
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998001
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pipelined function
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998041
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
UNION ALL в 11.2 гарантирует последовательное исполнение подзапросов, и сохранение их порядка как они записаны сверху вниз.
С чего ты взял?
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998045
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров
НеофитSQL
UNION ALL в 11.2 гарантирует последовательное исполнение подзапросов, и сохранение их порядка как они записаны сверху вниз.
С чего ты взял?

думаю, он имел в виду вот это: https://docs.oracle.com/database/121/VLDBG/GUID-1F4C90F9-3EF5-423A-B55B-2593FB3F1433.htm

поведение по умолчанию предполагает, что следующая ветка union all не начнет исполняться до окончания предыдущей. при этом я не нашел упоминания о том, в каком именно порядке эти ветки будут исполняться (в порядке как указано в запросе, или в каком-то ещё).

с другой стороны, а в каком ещё порядке они могут исполняться? что может побудить оптимизатор перемешать union all?
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998054
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кит северных морей
с другой стороны, а в каком ещё порядке они могут исполняться? что может побудить оптимизатор перемешать union all?

Ни разу не сталкивался с выполнением union all в порядке, отличном от исходного, что, однако, не отменяет того факта, что oracle все-таки не гарантирует этого и закладываться на это в боевом коде глупо.
И именно отсутствие этой гарантии и позволило включить параллельную обработку частей union all по умолчанию в 12 версии.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998055
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кит северных морей

с другой стороны, а в каком ещё порядке они могут исполняться? что может побудить оптимизатор перемешать union all?


Ну например parallel slaves или (гипотетически) RAC - разбросать по nodes. Результат - мешанина строк из разных частей UNION ALL.

SY.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998056
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Меня больше интересует принципиальные вопросы:
1. Если порядок важен, то почему не указан order by?
2. Какой смысл хотеть параллельного выполнения, если хочется, чтобы сначала вернулись строки в порядке указания частей union all? Ведь это означает лишнюю работу, если фетч прекратится досрочно и зря простаивающие слейвы пока фетчатся предыдущие части.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998060
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Ну например parallel slaves или (гипотетически) RAC - разбросать по nodes.
это вариант с PQ_CONCURRENT_UNION. я говорю именно о NO_PQ_CONCURRENT_UNION, т.е. когда каждая ветка выполняется с DOP > 1, и потенциально cross-instace, но при этом строго последовательно.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998063
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|
что, однако, не отменяет того факта, что oracle все-таки не гарантирует этого

косвенно гарантирует?

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/The-UNION-ALL-INTERSECT-MINUS-Operators.html#GUID-B64FE747-586E-4513-945F-80CB197125EE You can combine multiple queries using the set operators UNION, UNION ALL, INTERSECT, and MINUS. All set operators have equal precedence. If a SQL statement contains multiple set operators, then Oracle Database evaluates them from the left to right unless parentheses explicitly specify another order.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998065
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
кит северных морей

с другой стороны, а в каком ещё порядке они могут исполняться? что может побудить оптимизатор перемешать union all?
пока - ничто, но учитывая, что они никак не гарантировали, то в будущем могут легко изменять поведение. Например, переставлять в зависимости от order by, чтобы избежать сортировки, или переставлять более лёгкие части вперёд в случаях firsr_rows_n, и тд
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998067
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
кит северных морей
AlexFF__|
что, однако, не отменяет того факта, что oracle все-таки не гарантирует этого

косвенно гарантирует?

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/The-UNION-ALL-INTERSECT-MINUS-Operators.html#GUID-B64FE747-586E-4513-945F-80CB197125EE You can combine multiple queries using the set operators UNION, UNION ALL, INTERSECT, and MINUS. All set operators have equal precedence. If a SQL statement contains multiple set operators, then Oracle Database evaluates them from the left to right unless parentheses explicitly specify another order.
evaluates и executes - разные вещи. Это как and/or в where - логический порядок, но не порядок выполнения (кстати, если правильно помню, там как раз бывает, что порядок меняется на обратный из-за специфики парсинга)
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998186
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Потому что в стандарте SQL не определен порядок "по умолчанию".
Понятно, что он есть, но он может быть какой угодно.
Чтобы отсортировать в "правильном порядке", нужно указать как сортировать (по какому полю).

Так что все правильно Oracle делает.
А то что вы хотите это специфичная вещь, для конкретной реализации и привязываться к ней, это говнокод. С неизбежным получением в будущем кучи проблем.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998413
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем!

SY уже указал раздел документации, где Оракл гарантирует сохранение порядка UNION ALL "как записано на экране".

В https://docs.oracle.com/database/121/VLDBG/GUID-1F4C90F9-3EF5-423A-B55B-2593FB3F1433.htm сказано:
авторHowever, unlike the sequential processing of one branch after another, the concurrent processing does not guarantee an ordered return of the results of the individual branches.

Мое прочтение, что фраза " в отличие от последовательного исполнения, параллельное исполнение не гарантирует упорядоченный результат", гарантирует упорядоченный результат для не-параллельного исполнения, и несет вес документации производителя.

Вот один из менее трудоемких способов задать порядок возврата строчек "как в тексте", без ручной перенумерации при передвижении строк вверх/вниз, который пришел на ум:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
-- монотонно растущий счетчик для поддержки натурально упорядоченных UNION ALL запросов
create sequence sq
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1;

.........

select /*+ PQ_CONCURRENT_UNION(@"SET$1") */ val from (
  select sq.nextval, 'П' val from dual   union all
  select sq.nextval, 'р' from dual   union all
  select sq.nextval, 'и' from dual   union all
  select sq.nextval, 'м' from dual   union all
  select sq.nextval, 'е' from dual   union all
  select sq.nextval, 'р' from dual 
order by 1)



Пример упрощен для читабельности, в реальности многие из строк - кандидаты для параллельного исполнения.
Этот код отвечает моим требованиям: разрешить параллельное исполнение, сохранить порядок результата как в коде, не требовать ручной (и подверженной ошибкам) перенумерации при изменении порядок строчек в коде.
К сожалению, он полагается на то, что Оракл начнет исполнение в порядке написания, а таких гарантий у Оракла я не нашел.

По вопросам уважаемых участников:
xtender
Меня больше интересует принципиальные вопросы:
1. Если порядок важен, то почему не указан order by?
2. Какой смысл хотеть параллельного выполнения, если хочется, чтобы сначала вернулись строки в порядке указания частей union all? Ведь это означает лишнюю работу, если фетч прекратится досрочно и зря простаивающие слейвы пока фетчатся предыдущие части.


1. Order by - предпочтительный метод, я считаю. Полагаться на задокументируемые аспекты поведения - плохая практика.
К сожалению, не предусмотрен удобный ключ сортировки соответствующий номеру строки, как в PL/SQL.
Добавление числа вызывает неудобства ручной перенумерации, описанные в первом сообщении.
2. Смысл в том, чтобы время исполнения всего запроса не слишком превышало время исполнения самого долгого из подзапросов.
Например, подзапросы ходят в интернет, у которого при обрыве связи тайм аут может достигать десятки секунд. UNION ALL из сотни непараллельных запросов может подвиснуть на час, а параллельных - завершится в пределах минуты.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998429
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Вот один из менее трудоемких способов

Как уже писали в соседней ветке, надеюсь, никогда не придётся сопровождать ваш код.

НеофитSQL
Например, подзапросы ходят в интернет

А за такое по-хорошему надо сразу давать по рукам. Для решения задач параллельного сбора данных из вызовов веб-сервисов есть другие решения. И это не SQL.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998439
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

Этот код отвечает моим требованиям: разрешить параллельное исполнение, сохранить порядок результата как в коде, не требовать ручной (и подверженной ошибкам) перенумерации при изменении порядок строчек в коде.

имхо
Вы сами себе противоречете
"разрешить параллельное исполнение" подразумевает что результат может не сответствовать union all

если нужен/важен порядок то "как в старом бэйсике" нагляднее и понятнее, по крайней мере мне

.....
stax
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998474
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
env
Для решения задач параллельного сбора данных из вызовов веб-сервисов есть другие решения.
ну, справедливости ради, он нигде не сказал про веб-сервисы. под "ходят в интернет" мог подразумеваться db link.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998477
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кит северных морей,

Сомневаюсь, что ТС уже знает, что такое дб линки. По предыдущим постам - автор топика пытается натянуть функционал декларативной совы на императивный объектно-ориентированный глобус.


упд. по теме топика - порядок гарантирует только явный order by
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998481
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select /*+ PQ_CONCURRENT_UNION(@"SET$1") */ val from (
  select sq.nextval, 'П' val from dual   union all
  select sq.nextval, 'р' from dual   union all
  select sq.nextval, 'и' from dual   union all
  select sq.nextval, 'м' from dual   union all
  select sq.nextval, 'е' from dual   union all
  select sq.nextval, 'р' from dual 
order by 1)


Даже помимо
Код: plsql
1.
2.
ERROR at line 3:
ORA-02287: sequence number not allowed here


что вообще планировалось достичь добавлением сиквенса? Есть понимание как вообще работают сиквенсы в параллельных планах? Сиквенсы сейчас выполняются в отдельной непараллельной строке плана - операция так и называется "SEQUENCE"...
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998483
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
К сожалению, не предусмотрен удобный ключ сортировки соответствующий номеру строки, как в PL/SQL


Нет никакого номера строки пока не начался фетч (псевдостолбец rownum) или не будет задана явная сортировка набора данных. Пора бы уже прекратить ждать от множеств поведения им несвойственного.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998485
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
2. Смысл в том, чтобы время исполнения всего запроса не слишком превышало время исполнения самого долгого из подзапросов.
Основная ошибка у вас в том, что вы не понимаете как работают параллельные планы/операции... Пока слейв не передал свои данные координатору, он не запустит очередную итерацию дочерних операций. Соответственно, чтобы он продолжал "работать", надо чтобы координатор куда-то буферизовал полученные данные, пока их не отфетчат, что опять-таки приводит либо к блокирующим операциям типа BUFFER SORT или SORT ORDER BY. Так или иначе - это хрень полная
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998503
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender
НеофитSQL
2. Смысл в том, чтобы время исполнения всего запроса не слишком превышало время исполнения самого долгого из подзапросов.
Основная ошибка у вас в том, что вы не понимаете как работают параллельные планы/операции... Пока слейв не передал свои данные координатору, он не запустит очередную итерацию дочерних операций. Соответственно, чтобы он продолжал "работать", надо чтобы координатор куда-то буферизовал полученные данные, пока их не отфетчат, что опять-таки приводит либо к блокирующим операциям типа BUFFER SORT или SORT ORDER BY. Так или иначе - это хрень полная


Вполне возможно, что я не понимаю - новичок в SQL.

К сожалению, у меня пока недостает эрудиции понять ваше объяснение.
Мое понимание параллельности подзапросов было такое:
- оракл запускает несколько запросов одновременно. Для примера, три подзапроса А,Б,В все начались в пределах 10-миллисекунд.
- Подзапрос А продолжался 10 секунд, подзапрос Б 5 секунд, подзапрос В - 7 секунд. Порядок завершения: Б,В,А
- учитывая что задана сортировка через order by, результаты Б и В будут сидеть в памяти пока запрос А не завершится.
- когда запрос А завершится, результат будет отсортирован и выдан в порядке А,Б,В (это исходное условие).
- Параллелизм позволяет такую задачу решить за 10 секунд, вместо 22 секунд при последовательном исполнении.

Я интересовался, есть ли удобный, известный и практикуемый метод для задания сортировочного ключа, чтобы не прибегать к ручной нумерации а-ля бэйсик.

Хотя я теперь нашел решение этой задачи которое отвечает всем моим требованиям, из негодующих ответов можно заключить, что ручная нумерация а-ля бэйсик является предпочитаемым решением, из соображений читабельности.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998504
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
env
НеофитSQL
К сожалению, не предусмотрен удобный ключ сортировки соответствующий номеру строки, как в PL/SQL


Нет никакого номера строки пока не начался фетч (псевдостолбец rownum) или не будет задана явная сортировка набора данных. Пора бы уже прекратить ждать от множеств поведения им несвойственного.


Ваш ответ возможно верен для другого случая, но rownum к этой задаче не относится. Меня интересует порядок запросов в исходном коде, и PL/SQL содержит макро для этого. SQL, увы, его не содержит.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998513
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
env
Для решения задач параллельного сбора данных из вызовов веб-сервисов есть другие решения. И это не SQL.


Оракл не рекомендуется использовать для хождения в интернет?
Это связано с отсутствием хороших библиотек, или есть другие причины?
Пожалуйста расскажите, какие решения предпочтительны в таком случае?

Допустим, к примеру*, у меня задача показать в запросе первые 10 сообщений из каждого из трех email почтовых ящиков на разных континентах. Если сортировка не требуется, я могу написать следующее:

Код: plsql
1.
2.
3.
4.
-- Функция FetchNewestEmails() возвращает таблицу
select FetchNewestEmails( 'imap:server1', credentials1, limit => 10 ) union all
select FetchNewestEmails( 'imap:server2', credentials2, limit => 10 ) union all
select FetchNewestEmails( 'imap:server3', credentials3, limit => 10 )



Через некоторое время, в зависимости от интернет соединения и здоровья серверов, запрос вернет до 30 строчек, где группы от разных серверов будут в неопределенном порядке - скорее всего в порядке завершения подзапросов, предполагая параллельное исполнение. Вопрос сортировки не трогаю, он уже решен в другом ответе.

Если такой код вызывает ужас и отвращение, то как лучше, и в чем его недостатки.

(*) пример придуманный, потому что у меня в данный момент нет задач требующих параллельного исполнения. Я задаю вопросы вне сферы своих задач, потому что это помогает учить SQL и ознакомиться с общепринятыми методами.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998514
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL,

Теперь все понятно, ваше понимание параллельного выполнения неверно, оттого и все проблемы и изчально странный вопрос. Вам стоит это изучить досконально, тогда и этот вопрос бы не появился. Пока достаточно вам запомнить, что никакого порядка нет пока не указан order by.
...
Рейтинг: 0 / 0
Сохранение порядка строк в UNION ALL
    #39998524
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
Код: plsql
1.
2.
3.
select FetchNewestEmails( 'imap:server1', credentials1, limit => 10 ) union all
select FetchNewestEmails( 'imap:server2', credentials2, limit => 10 ) union all
select FetchNewestEmails( 'imap:server3', credentials3, limit => 10 )

У вас еще нет понимания как работают параллельные запросы, как работает SEQUENCE, а теперь опять еще один прыжок к параллельному выполнению функций... По умолчанию, даже с concurrent union они будут выполнены в serial, а не в параллели. Желание объять "все и сразу" - понятно, но с ораклом так не получится. Пока это выглядит как будто уличный лекарь-калекарь советует выпить все таблетки разом, которые врач прописал пить по одной раз в день в течение месяца - мол, так быстрее...
...
Рейтинг: 0 / 0
25 сообщений из 51, страница 1 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Сохранение порядка строк в UNION ALL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]