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

Код: 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
12.09.2020, 23:28
    #39998001
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
pipelined function
...
Рейтинг: 0 / 0
13.09.2020, 11:28
    #39998041
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
НеофитSQL
UNION ALL в 11.2 гарантирует последовательное исполнение подзапросов, и сохранение их порядка как они записаны сверху вниз.
С чего ты взял?
...
Рейтинг: 0 / 0
13.09.2020, 11:59
    #39998045
кит северных морей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
Вячеслав Любомудров
Неофит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
13.09.2020, 13:27
    #39998054
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
кит северных морей
с другой стороны, а в каком ещё порядке они могут исполняться? что может побудить оптимизатор перемешать union all?

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

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


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

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

с другой стороны, а в каком ещё порядке они могут исполняться? что может побудить оптимизатор перемешать union all?
пока - ничто, но учитывая, что они никак не гарантировали, то в будущем могут легко изменять поведение. Например, переставлять в зависимости от order by, чтобы избежать сортировки, или переставлять более лёгкие части вперёд в случаях firsr_rows_n, и тд
...
Рейтинг: 0 / 0
13.09.2020, 14:02
    #39998067
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
кит северных морей
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
14.09.2020, 07:57
    #39998186
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
НеофитSQL,

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

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

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
14.09.2020, 17:09
    #39998429
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
НеофитSQL
Вот один из менее трудоемких способов

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

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

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

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

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

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

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

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


упд. по теме топика - порядок гарантирует только явный order by
...
Рейтинг: 0 / 0
14.09.2020, 18:26
    #39998481
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
Неофит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
14.09.2020, 18:29
    #39998483
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
НеофитSQL
К сожалению, не предусмотрен удобный ключ сортировки соответствующий номеру строки, как в PL/SQL


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


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

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

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

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


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


Ваш ответ возможно верен для другого случая, но rownum к этой задаче не относится. Меня интересует порядок запросов в исходном коде, и PL/SQL содержит макро для этого. SQL, увы, его не содержит.
...
Рейтинг: 0 / 0
14.09.2020, 19:31
    #39998513
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
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
14.09.2020, 19:32
    #39998514
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
НеофитSQL,

Теперь все понятно, ваше понимание параллельного выполнения неверно, оттого и все проблемы и изчально странный вопрос. Вам стоит это изучить досконально, тогда и этот вопрос бы не появился. Пока достаточно вам запомнить, что никакого порядка нет пока не указан order by.
...
Рейтинг: 0 / 0
14.09.2020, 19:53
    #39998524
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение порядка строк в UNION ALL
Неофит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
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Сохранение порядка строк в UNION ALL / 25 сообщений из 51, страница 1 из 3
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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