powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Близкострочные операции
52 сообщений из 52, показаны все 3 страниц
Близкострочные операции
    #40011054
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задумался - а как в SQL делается поиск не по строчке, не по группе, а по отношению к соседним строчкам (когда задан сортировочный порядок, естессно).

Нашел LAG(), что делает такие операции простыми, но непонятно как справлялись до нее. Очевидное решение - циклом, но тогда оптимизатор не у дел.

Например, не используя встроенную функцию LAG или подобные, как можно быстро из таблицы в миллионы строк найти все локальные минимумы для val?

В таблице две колонки: id/PK и val/number.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011066
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQLЗадумался
ты не думай, ты читай
читай
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011070
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
123йй
НеофитSQLЗадумался

ты не думай, ты читай
читай

Я вас тут раньше не видел, вы наверное новенький.

В Оракле сортировка делается оператором "order by".
Какой именно алгоритм, я не знаю, но сортировка по индексу очень эффективна, свою писать вряд ли есть необходимость.

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

Например.в ряде 3 2 7 4 3 8 локальные минимумы находятся в позициях 2 и 5.

С помощью цикла, или встроенной функции Lag() эта задача решается в пару строчек, второй эффективнее первого.

Мне интересно, среди людей которые помнят разницу между сортировкой и поиском минимумов, встречался ли кто-то с такой задачей?

Есть более простая но похожая задача - эффективно найти самый большой промежуток в уже отсортированном ряде чисел, средствами SQL не используя LAG().
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011074
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычно это делалось через упорядочивание, нумерование, и самосоединение (self-join) или деревяшка (connect by)
В этом случае есть гарантия что следующая строка будет как номер текущей+1
Если есть подходящий индекс, то можно по минимумам/максимумам превышающих/непревышающих значений порядка
Что-то типо такого
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
SQL> create table t_neofit (id primary key, val) as select rownum, trunc(dbms_random.value(1, 1000)) from dual connect by level <= 10;

Table created.

SQL> with t as (
  2       select a.id, a.val, b.id next_id, b.val next_val
  3       from t_neofit a, t_neofit b
  4       where b.id=(select min(id) from t_neofit where id > a.id)
  5  ), d as (
  6       select t.*, next_val-val diff, sign(next_val-val) sdiff from t
  7  ), diffs as (
  8       select a.*, b.next_id next_next_id, b.next_val next_next_val, b.diff next_diff, b.sdiff next_sdiff
  9       from d a, d b
 10       where b.id=(select min(id) from t_neofit where id > a.id)
 11  )
 12  select id from_id, next_id id, next_next_id to_id, val from_value, next_val value, next_next_val to_value,
 13         case when sdiff=-1 and next_sdiff=1 then '*' end minimum
 14   from diffs;

   FROM_ID         ID      TO_ID FROM_VALUE      VALUE   TO_VALUE M
---------- ---------- ---------- ---------- ---------- ---------- -
         1          2          3        272        759        336
         2          3          4        759        336        773 *
         3          4          5        336        773        543
         4          5          6        773        543        182
         5          6          7        543        182        335 *
         6          7          8        182        335        622
         7          8          9        335        622         47
         8          9         10        622         47        139 *

8 rows selected.

SQL> @plan_last

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bhcxzht2xk7sy, child number 0
-------------------------------------
with t as (      select a.id, a.val, b.id next_id, b.val next_val
from t_neofit a, t_neofit b      where b.id=(select min(id) from
t_neofit where id > a.id) ), d as (      select t.*, next_val-val diff,
sign(next_val-val) sdiff from t ), diffs as (      select a.*,
b.next_id next_next_id, b.next_val next_next_val, b.diff next_diff,
b.sdiff next_sdiff      from d a, d b      where b.id=(select min(id)
from t_neofit where id > a.id) ) select id from_id, next_id id,
next_next_id to_id, val from_value, next_val value, next_next_val
to_value,        case when sdiff=-1 and next_sdiff=1 then '*' end
minimum  from diffs

Plan hash value: 2458627781

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                             |       |       |    19 (100)|          |
|   1 |  TEMP TABLE TRANSFORMATION        |                             |       |       |            |          |
|   2 |   LOAD AS SELECT                  |                             |       |       |            |          |
|   3 |    NESTED LOOPS                   |                             |       |       |            |          |
|   4 |     NESTED LOOPS                  |                             |     1 |    52 |    13   (0)| 00:00:01 |
|   5 |      TABLE ACCESS FULL            | T_NEOFIT                    |    10 |   260 |     3   (0)| 00:00:01 |
|*  6 |      INDEX UNIQUE SCAN            | SYS_C0079998                |     1 |       |     0   (0)|          |
|   7 |       SORT AGGREGATE              |                             |     1 |    13 |            |          |
|   8 |        FIRST ROW                  |                             |     1 |    13 |     1   (0)| 00:00:01 |
|*  9 |         INDEX RANGE SCAN (MIN/MAX)| SYS_C0079998                |     1 |    13 |     1   (0)| 00:00:01 |
|  10 |     TABLE ACCESS BY INDEX ROWID   | T_NEOFIT                    |     1 |    26 |     1   (0)| 00:00:01 |
|* 11 |   FILTER                          |                             |       |       |            |          |
|  12 |    MERGE JOIN CARTESIAN           |                             |     1 |   117 |     4   (0)| 00:00:01 |
|  13 |     VIEW                          |                             |     1 |    65 |     2   (0)| 00:00:01 |
|  14 |      TABLE ACCESS FULL            | SYS_TEMP_0FD9D6611_13C03C8B |     1 |    52 |     2   (0)| 00:00:01 |
|  15 |     BUFFER SORT                   |                             |     1 |    52 |     4   (0)| 00:00:01 |
|  16 |      VIEW                         |                             |     1 |    52 |     2   (0)| 00:00:01 |
|  17 |       TABLE ACCESS FULL           | SYS_TEMP_0FD9D6611_13C03C8B |     1 |    52 |     2   (0)| 00:00:01 |
|  18 |    SORT AGGREGATE                 |                             |     1 |    13 |            |          |
|  19 |     FIRST ROW                     |                             |     1 |    13 |     1   (0)| 00:00:01 |
|* 20 |      INDEX RANGE SCAN (MIN/MAX)   | SYS_C0079998                |     1 |    13 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - access("B"."ID"=)
   9 - access("ID">:B1)
  11 - filter("B"."ID"=)
  20 - access("ID">:B1)

Note
-----
   - dynamic sampling used for this statement (level=2)


53 rows selected.

Но профессионалы-разработчики наверное и более лучший вариант подскажут
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011077
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
локальный минимум - это когда ближайшие левое и правое значение больше среднего?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011080
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

Есть более простая но похожая задача - эффективно найти самый большой промежуток в уже отсортированном ряде чисел, средствами SQL не используя LAG().


зачем lag, есть же match_recognize (в примере какраз ищут W)

гляньте Oracle для профессионалов Том Кайт (есть отличный перевод)
там примеры как "без LAG"
авторSQL — очень мощный язык и лишь очень немногие запросы в нем нельзя создать.
По опыту знаю, что можно придумать хитрый SQL-запрос для получения ответа прак-
тически на любой вопрос относительно любых данных. Однако производительность
некоторых из этих запросов крайне низкая
, да и придумать их непросто. Ряд запросов,
которые сложно сформулировать на обычном языке SQL, весьма типичны:
....
Аналитические функции, появившиеся в версии Oracle 8.1.6, создавались для реше-
ния именно этих задач. Они расширяют язык SQL так, что подобные операции не толь-
ко проще записываются, но и быстрее выполняются по сравнению с использованием
чистого языка SQL.


ps
почему 5
Например.в ряде 3 2 7 4 3 8 локальные минимумы находятся в позициях 2 и 5 .


.....
stax
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011082
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx
не усложняй.ему подходит Lag. поэтому
если значание слева и справа больше - значит это локальный минимум
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011086
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Я вас тут раньше не видел, вы наверное новенький.

Восхохотамши под лавкою.

Действительно, все, кто по какой-то причине не стал отвечать в предыдущих ваших темах точно новички. Не в профиле же смотреть, с какого года человек на форуме.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011155
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL
Задумался - а как в SQL делается поиск не по строчке, не по группе, а по отношению к соседним строчкам (когда задан сортировочный порядок, естессно).

Нашел LAG(), что делает такие операции простыми, но непонятно как справлялись до нее. Очевидное решение - циклом, но тогда оптимизатор не у дел.

Например, не используя встроенную функцию LAG или подобные, как можно быстро из таблицы в миллионы строк найти все локальные минимумы для val?

В таблице две колонки: id/PK и val/number.

Как же ты любишь забивать гвозди микроскопом и не желаешь учиться))

SQL создавался не для инженерных расчетов и не для поисков экстремумов функций или числовых рядов, эти задачи решают с помощью императивных языков.

"id/PK и val/number" - таблица представляет собой кучу, первичный ключ не отвечает за последовательность записей, другими словами для твоего ряда 3 2 7 4 3 8 ты должен определить поле по которому ты получишь именно такой порядок сортировкой.

"как справлялись до нее" - императивные языки, но ты можешь написать запрос и без lag, он очень простой, справишься?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011158
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
123йй
не усложняй.ему подходит Lag.

На самом деле не подходит, 3 2 7 4 3 3 3 3 2 8.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011162
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
С помощью цикла, или встроенной функции Lag() эта задача решается в пару строчек, второй эффективнее первого.
бред. На большом наборе(например, попробуй на паре миллионов записей) цикл будет эффективнее. Задача идеально решается с помощью match_recognize, но тебе с твоей 11.2.0.1 он не светит. Решений на оракле вообще масса - еще не перечислены другие аналитические функции (причем аналитический min()over(order by ... rows between 1 preceding and 1 following) гораздо интуитивнее, чем lag(), но ты же доку не читаешь и других функций не знаешь...), рекурсивный cte, model и тд
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011168
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
graycode
Как же ты любишь забивать гвозди микроскопом и не желаешь учиться))
+1. Сам себе идиотские ограничения придумывает, да еще и книжки и доку игнорирует


graycode
123йй
не усложняй.ему подходит Lag.

На самом деле не подходит, 3 2 7 4 3 3 3 3 2 8.
пойдут lag/lead, просто следующее должно быть больше текущего
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011174
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender
пойдут lag/lead, просто следующее должно быть больше текущего

На "площадке" неизвестно является ли она локальным минимумом, длина ее тоже неизвестна, т.е. если убрать 2, то вся площадка с трешками является локальным минимумом.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011187
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
graycode,

последняя трешка выведется, а нужно ли реально все выводить? и если нужно, то не лучше ли их сначала в диапазоны свернуть
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011207
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
graycode
123йй
не усложняй.ему подходит Lag.

На самом деле не подходит, 3 2 7 4 3 3 3 3 2 8.

ты знаешь лучше ТС что ему надо ?
авторС помощью цикла, или встроенной функции Lag() эта задача решается в пару строчек, второй эффективнее первого.

ЗЫж andreymx. не сразу понял какой смысл несет слово "среднее".
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011210
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender,

Вы правы, если свернуть в диапазоны, то хватит lead/lag.

Что нужно, что нет, да кто же этого неофита знает что ему нужно, понятно только одно, нахождением экстремумов функций он тоже не занимался))
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011212
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with t(n, val) as (select rownum, column_value from table(sys.odcinumberlist(
-1,3,2,7,10,5,5,5,5,3,8,0,0,0,0,1,2,3,-1
)))
select *
from t
match_recognize (
  order by n
  measures 
      first(s.n) as first_n,
      last(s.n) last_n,
      min(s.val) as lmin
  pattern (s+ u+)
  define 
    s as val <= least(prev(val),next(val)),
    u as val > prev(val)
);

   FIRST_N     LAST_N       LMIN
---------- ---------- ----------
         3          3          2
        10         10          3
        12         15          0

+nvl при необходимости обработки крайних точек
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011237
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

1,2,2,2,3

ps
1,2,3

3,2,1

1

.....
stax
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011264
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Stax,


xtender
+nvl при необходимости обработки крайних точек


с крайними точками
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  with t(n, val) as (select rownum, column_value from table(sys.odcinumberlist(
  1,2,2,2,3
  )))
  select *
  from t
  match_recognize (
    order by n
    measures 
        first(d.n) as first_n,
        last(d.n) last_n,
        min(d.val) as lmin
    --all rows per match with unmatched rows
    pattern (d*)
    define 
      d as (val < prev(val) or prev(val) is null) and nvl(next(val),val) >= d.val
  );


вообще я не думаю, что крайние точки должны учитываться, т.к. у них окрестность не определена
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011284
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender

вообще я не думаю, что крайние точки должны учитываться, т.к. у них окрестность не определена


Неофит ищет минимум (не V|U), поетому карайние надо учитывать
хотя, надо уточнять у бухов

.....
stax
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011294
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав Любомудров,

Круто. Я вчера ломал голову как для решения такой задачи селф-джойн таблицу с непоследовательными ID, пока не вспомнил про rownum. D'oh! Наверное и через rank() можно селф-джойнить.

Из вашего примера я вижу что через селф-джойн функция LAG эмулируется, и возможно очень эффективно.

Спасибо, очень полезный прием. Я копал в этом направлении, но пока не вспомнил про rownum, мой подход требовал ключа без дырок.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011305
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender
НеофитSQL
С помощью цикла, или встроенной функции Lag() эта задача решается в пару строчек, второй эффективнее первого.
бред. На большом наборе(например, попробуй на паре миллионов записей) цикл будет эффективнее.


Я ожидал, что цикл хуже, т.к. не параллелится. Вот самый короткий цикл для простого случая (без обработки плато, или конечных точек)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
prev TESTl%ROWTYPE;
diff TEST.val%TYPE;
...

for trow in (select val from TEST order by id)
loop
  if diff < 0 and trow.val > prev.val 
  then 
    -- prev содержит локальный минимум
  end if;
  diff := trow.val -prev.val;
  prev := trow;
end loop;



У вас наверное есть последний и могучий Оракл, с помощью которого можно легко сравнить тупой цикл и умные подходы со встроенными специализированными функциями.

Вы считаете что на двух миллионах строчек цикл Неофита обгонит контору инженеров Оракла на этой несложной задаче?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011310
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
xtender

вообще я не думаю, что крайние точки должны учитываться, т.к. у них окрестность не определена


Неофит ищет минимум (не V|U), поетому карайние надо учитывать
хотя, надо уточнять у бухов

.....
stax


Я не знаю кто такие бухи, но в данном случае интересовался общей идеей поиска по массиву без цикла.
Было несколько полезных ответов, а также упоминания оконных функций и новой для 12.х функции match, о которой я не знал.

Остается нераскрытым вопрос, так ли плох цикл для скорости запроса как его малюют в учебниках и руководствах.
Надеюсь, xtender или другой опытный ораклист это сможет прояснить.
Цикл я написал в другом сообщении, там места для оптимизации немного.
Смотрит на строчки по одной, скорость линейная, индексы не помогают.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011317
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
кто такие бухи

Бухгалтеры. Зачастую постановки задач на поиск минимума в цепочке сумм накладных, но с перламутровыми пуговицами, и только если Сатурн был в Тельце три последних дня по производственному календарю Бангладеша, приходят от них. Стас в основном в этой предметной области работает.

НеофитSQL
Цикл я написал в другом сообщении, там места для оптимизации немного

Попробуйте с коллекциями.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011332
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL
Я ожидал, что цикл хуже, т.к. не параллелится.

Многопоточность в других языках программирования уже отменили?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011336
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
У вас наверное есть последний и могучий Оракл

Держите, сравнивайте

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
SQL> set serverout on
SQL> set timing on
SQL>
SQL> drop table dropme_t purge;

Table dropped.

Elapsed: 00:00:00.03
SQL>
SQL> create table dropme_t as select level n, trunc(dbms_random.value(1,100)) m from dual connect by level <= 1e6;

Table created.

Elapsed: 00:00:08.95
SQL>
SQL> with t as
  2  (
  3      select m, lead(m,1) over(order by n) next, lag(m,1) over(order by n) prev from dropme_t
  4  )
  5  select
  6      count(*) cnt
  7  from
  8      t
  9  where
 10      m < next and
 11      m < prev
 12  /

       CNT
----------
    328192

Elapsed: 00:00:01.91
SQL>
SQL> declare
  2      type t_t is table of dropme_t%rowtype index by binary_integer;
  3      v_t t_t;
  4      diff_cnt number := 0;
  5  begin
  6      select * bulk collect into v_t from dropme_t order by n;
  7      for v in v_t.first..v_t.last loop
  8          if v>1 and v<v_t.count then
  9              if v_t(v).m < v_t(v-1).m and v_t(v).m < v_t(v+1).m then
 10                  --dbms_output.put_line(v_t(v-1).n||':'||v_t(v-1).m||' '||v_t(v).n||':'||v_t(v).m||' '||v_t(v+1).n||':'||v_t(v+1).m);
 11                  diff_cnt := diff_cnt + 1;
 12              end if;
 13          end if;
 14      end loop;
 15      dbms_output.put_line(diff_cnt);
 16  end;
 17  /
328192

PL/SQL procedure successfully completed.

Elapsed: 00:00:01.31
SQL>
SQL> declare
  2      prev dropme_t%rowtype;
  3      diff dropme_t.n%type;
  4      diff_cnt number:=0;
  5  begin
  6      select * into prev from dropme_t where n = 1; --(select min(n) from dropme_t);
  7
  8      for trow in (select n, m from dropme_t order by n) loop
  9          if diff < 0 and trow.m > prev.m
 10          then
 11              diff_cnt := diff_cnt + 1;
 12          end if;
 13          diff := trow.m -prev.m;
 14          prev.n := trow.n;
 15          prev.m := trow.m;
 16      end loop;
 17      dbms_output.put_line(diff_cnt);
 18  end;
 19  /
328192

PL/SQL procedure successfully completed.

Elapsed: 00:00:04.16
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011342
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
env,

не знаю, что вы делаете, но if из цикла надо убирать:

Код: plsql
1.
for v in v_t.first+1..v_t.last-1 loop



отдельно и дополнительно надо понять, а для двух элементов ответ есть или нет?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011344
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
env,

не знаю, что вы делаете, но if из цикла надо убирать:

Код: plsql
1.
for v in v_t.first+1..v_t.last-1 loop



отдельно и дополнительно надо понять, а для двух элементов ответ есть или нет?


вообще-то, может оказаться неплохо подумать, а как жить на миллиардах и с широкими записями...
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011353
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
graycode
НеофитSQL
Я ожидал, что цикл хуже, т.к. не параллелится.

Многопоточность в других языках программирования уже отменили?


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

Многопоточный цикл для линейного поиска по одной таблице звучит как приглашение хорошо получить граблями, даже для опытных кодеров. Вы попробуйте такой код здесь опубликовать, и быстро соберете список недочетов.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011357
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL
Я понятия не имею как в PL/SQL сделать многопоточный цикл, и будет ли от него толк в этом случае.

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

Зачем в PL/SQL? В java или C# нет многопоточности?

От Оракла требуется только отдать отсортированные данные, хотя можешь и сам отсортировать, дальше уже твоя забота, разбить полученное отсортированное множество на секции и обработать каждую секцию в своем потоке, склеить результат, все.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011358
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
env,

то есть, ваш цикл с массивами, (если он на самом деле делает то, что подразумевается в задаче)
мог бы так выглядеть.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
declare
      type t_t is table of dropme_t%rowtype index by binary_integer;
      v_t t_t;
     -- diff_cnt number := 0;
      diff_cnt pls_integer := 0;
  begin
      select * bulk collect into v_t from dropme_t order by n;
      for v in v_t.first+1..v_t.last-1 loop
         
         continue when not (v_t(v).m < v_t(v-1).m and v_t(v).m < v_t(v+1).m);
         
         --dbms_output.put_line(v_t(v-1).n||':'||v_t(v-1).m||' '||v_t(v).n||':'||v_t(v).m||' '||v_t(v+1).n||':'||v_t(v+1).m);
         diff_cnt := diff_cnt + 1;
      
      end loop;
      dbms_output.put_line(diff_cnt);
  end;
/



без проверки.
объективно должно быть быстрее.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011362
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

если на самом деле понятно, что такое
авторМногопоточный цикл для линейного поиска по одной таблице
то сымитировать его в pl/sql есть, по крайней мере, два пути - канальные функции и джобы.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011393
проходил мимо...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
канальные функции и джобы.

IPC не впечатляет...
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011396
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
env
Держите, сравнивайте
первый селект лишний был у тебя:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
with t as
(
    select m, lead(m,1) over(order by n) next, lag(m,1) over(order by n) prev from dropme_t
)
select
    count(*) cnt
from
    t
where
    m < next and
    m < prev
/
       CNT
----------
    328470

Elapsed: 00:00:01.22

declare
    prev dropme_t%rowtype;
    diff boolean := true;
    diff_cnt number:=0;
begin
    for trow in (select n, m from dropme_t order by n) loop
        if diff and trow.m > prev.m
        then
            diff_cnt := diff_cnt + 1;
        end if;
        diff := trow.m < prev.m;
        prev.n := trow.n;
        prev.m := trow.m;
    end loop;
    dbms_output.put_line(diff_cnt);
end;
/

328470

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.68

...
Рейтинг: 0 / 0
Близкострочные операции
    #40011399
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
graycode
НеофитSQL
Я понятия не имею как в PL/SQL сделать многопоточный цикл, и будет ли от него толк в этом случае.

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

Зачем в PL/SQL? В java или C# нет многопоточности?

От Оракла требуется только отдать отсортированные данные, хотя можешь и сам отсортировать, дальше уже твоя забота, разбить полученное отсортированное множество на секции и обработать каждую секцию в своем потоке, склеить результат, все.


А, я понял о чем вы. Что для максимальной скорости для такой простой задачи надо данные взять в память и передать во внешнюю процедуру обработки. Тогда это простая задача для другого языка, где больше времени будет потрачено на передачу данных, чем на сам поиск.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011400
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
Я ожидал, что цикл хуже, т.к. не параллелится.
рано тебе в параллель лезть и чего-то ожидать не зная, как работает параллельное выполнение в оракле.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Plan hash value: 591295248

--------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |          |     1 |    39 |    74   (7)| 00:00:01 |        |      |            |
|   1 |  SORT AGGREGATE            |          |     1 |    39 |            |          |        |      |            |
|*  2 |   VIEW                     |          |  1000K|    37M|    74   (7)| 00:00:01 |        |      |            |
|   3 |    WINDOW BUFFER           |          |  1000K|  7812K|    74   (7)| 00:00:01 |        |      |            |
|   4 |     PX COORDINATOR         |          |       |       |            |          |        |      |            |
|   5 |      PX SEND QC (ORDER)    | :TQ10001 |  1000K|  7812K|    74   (7)| 00:00:01 |  Q1,01 | P->S | QC (ORDER) |
|   6 |       SORT ORDER BY        |          |  1000K|  7812K|    74   (7)| 00:00:01 |  Q1,01 | PCWP |            |
|   7 |        PX RECEIVE          |          |  1000K|  7812K|    70   (2)| 00:00:01 |  Q1,01 | PCWP |            |
|   8 |         PX SEND RANGE      | :TQ10000 |  1000K|  7812K|    70   (2)| 00:00:01 |  Q1,00 | P->P | RANGE      |
|   9 |          PX BLOCK ITERATOR |          |  1000K|  7812K|    70   (2)| 00:00:01 |  Q1,00 | PCWC |            |
|  10 |           TABLE ACCESS FULL| DROPME_T |  1000K|  7812K|    70   (2)| 00:00:01 |  Q1,00 | PCWP |            |
--------------------------------------------------------------------------------------------------------------------

...
Рейтинг: 0 / 0
Близкострочные операции
    #40011402
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
booby
то сымитировать его в pl/sql есть,
dbms_parallel_execute
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011403
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender
env
Держите, сравнивайте
первый селект лишний был у тебя:

==>Elapsed: 00:00:01.22 -- SQL

==>Elapsed: 00:00:00.68 -- цикл



Простой цикл без кэширования данных побеждает с отрывом вдвое!
Если у нет дополнительных SQL секретов, это возможно просто не та задача, где оптимизатор Оракла может помочь.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011404
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL
А, я понял о чем вы. Что для максимальной скорости для такой простой задачи надо данные взять в память и передать во внешнюю процедуру обработки. Тогда это простая задача для другого языка, где больше времени будет потрачено на передачу данных, чем на сам поиск.

А в чьей светлой головушке вдруг взялись мысли о том чтобы параллелить цикл для такой простой задачи?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011407
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
Если у нет дополнительных SQL секретов, это возможно просто не та задача, где оптимизатор Оракла может помочь.
просто не тебе с 11.2.0.1
требуется допилить, но мне лень и некогда
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SQL> ;
  1  select count(*) cnt
  2  from dropme_t t
  3  match_recognize (
  4      order by n
  5      measures
  6          last(d.m) as lmin
  7      one row per match
  8      pattern (s d+)
  9      define
 10        d as m > prev(m)
 11*   )
SQL> /

       CNT
----------
    333447

Elapsed: 00:00:00.83

...
Рейтинг: 0 / 0
Близкострочные операции
    #40011408
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
graycode
А в чьей светлой головушке вдруг взялись мысли о том чтобы параллелить цикл для такой простой задачи?
++++
да, это самый правильный вопрос во всех темах ТСа
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011447
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
booby
то сымитировать его в pl/sql есть,
dbms_parallel_execute

баги-то они в нём вылечили со сваливанием всего в один поток?

Так-то замечтательно, конечно.
Но джобы на коленке и веревочках, б о льшую степень веры в управляемость внушают.
И особенно, когда оснастки под них унаследованы от славных предшественников за пару версий до появления dbms_parallel_execute.

Оно конечно, - плесень и несовременно.
Но свежемолодым подходом потрахивать - это надо глубокой степенью невинности располагать.
Не всем это по возрасту положено.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011455
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проходил мимо...
booby
канальные функции и джобы.

IPC не впечатляет...

а как она должна быть использована именно в этой задаче?
(формулировку которой я не вполне понял - все черти в неозвученных деталях)

Там где IPC очевидно нужна - в пользовательских агрегатах - она тщательно представлена чёрным ящиком.
Ляпота. Сиди себе, стандартные интерфейсы выписывай и в потолок поплёвывай.

Вот недавно совсем человек докладывал, как он с IPC в Oracle боролся и побеждал:
https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1326622&msg=22158286
https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1326622&msg=22158461

и, как вполне очевидно из текста, до сих пор гордится достигнутыми результатами.
(Это не для смеха и хохота ссылки, а на подумать о предметах гордости).

Возвращаясь к джобам - если сказано джоб, так за IPC расстрел на месте,
без торжественного построения рассматривающих расстрел.
:)
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011461
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
graycode
НеофитSQL
А, я понял о чем вы. Что для максимальной скорости для такой простой задачи надо данные взять в память и передать во внешнюю процедуру обработки. Тогда это простая задача для другого языка, где больше времени будет потрачено на передачу данных, чем на сам поиск.

А в чьей светлой головушке вдруг взялись мысли о том чтобы параллелить цикл для такой простой задачи?


Вообще-то у вас. Я предложил что цикл параллелить непродуктивно, и похоже вы теперь с этим уже согласны.

22219709

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

Например, env улучшил скорость цикла, пожертвовав несколькими мегабайтами памяти. Bulk collect в массив и последующий доступ к массиву заметно быстрее чем цикл по таблице.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011463
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пока цикл неоспоримый лидер, прикладная польза от LAG/LEAD() не вполне понятна. Они делают то же, что и цикл, только медленее?

Или бывают задачи, где LAG() не только полезна, но ещё и быстрее простого цикла?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011467
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL
Вообще-то у вас. Я предложил что цикл параллелить непродуктивно, и похоже вы теперь с этим уже согласны.

22219709

Где ты предположил что цикл параллелить непродуктивно? Ты напротив написал что цикл хуже , так как не параллелится или ты уже не в состоянии понять то что сам же и написал?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011475
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
graycode
НеофитSQL
Вообще-то у вас. Я предложил что цикл параллелить непродуктивно, и похоже вы теперь с этим уже согласны.

22219709

Где ты предположил что цикл параллелить непродуктивно? Ты напротив написал что цикл хуже , так как не параллелится или ты уже не в состоянии понять то что сам же и написал?


Охотно поясню. Я выразил мнение что решение с циклом хуже, т.к. циклы плохо поддаются параллельной оптимизации.

Вы сказали что "а у нас в джаве циклы можно параллелить".

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

Возможно, я неверно вас понял, и вы все еще хотите эту задачу решать многопоточно через джаву. Я не против, попробуйте.
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011477
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я попробовал измерить скорость этой задачи через селф-джойн (как предложил Вячеслав),
получилось заметно быстрее простого цикла.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
SQL> declare
  2      prev dropme_t%rowtype;
  3      diff boolean := true;
  4      diff_cnt number:=0;
  5  begin
  6      for trow in (select n, m from dropme_t order by n) loop
  7          if diff and trow.m > prev.m
  8          then
  9              diff_cnt := diff_cnt + 1;
 10          end if;
 11          diff := trow.m < prev.m;
 12          prev.n := trow.n;
 13          prev.m := trow.m;
 14      end loop;
 15      dbms_output.put_line(diff_cnt);
 16  end;
 17  /
328441
PL/SQL procedure successfully completed
Executed in 2,468 seconds

SQL> select count(*) from dropme_t t1 join dropme_t t2 on t1.n+1=t2.n join dropme_t t3 on t1.n-1=t3.n where t2.m>t1.m and t3.m>t1.m;
  COUNT(*)
----------
    328441
Executed in 1,812 seconds



Это потому, что я индекс включил, или просто у Оракла в старых версиях циклы плохо работали?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011478
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это потому что у тебя вырожденный случай -- нумерация очередности без пропусков
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011480
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав Любомудров
Это потому что у тебя вырожденный случай -- нумерация очередности без пропусков


Да, мне надо было свою таблицу делать, а не тырить у env.
Мне понравилось лаконичное заполнение, и я позаимствовал.

Кстати, кто то ещё заметил, насколько близко в разных тестах совпало число минимумов для 1м строк?
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011481
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров
Это потому что у тебя вырожденный случай -- нумерация очередности без пропусков

не, ставлю сто пудов на то, что у него построчный фетч.
Конкретно в этом бессмысленном примере других причин быть не должно.

Т.е., либо plsql_debug = true, либо plsql_optimize_level меньше 2-ки
выполни перед запуском скрипта:

Код: plsql
1.
2.
alter session set plsql_debug = false;
alter session set plsql_optimize_level = 2;
...
Рейтинг: 0 / 0
Близкострочные операции
    #40011528
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL
Охотно поясню. Я выразил мнение что решение с циклом хуже, т.к. циклы плохо поддаются параллельной оптимизации.

Вы сказали что "а у нас в джаве циклы можно параллелить".

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

Возможно, я неверно вас понял, и вы все еще хотите эту задачу решать многопоточно через джаву. Я не против, попробуйте.

И тут Остапа понесло ... даже не брезгует выдумывать цитаты))

Там где у тебя возникают глупые идеи параллелить цикл, нормальные люди начинают серьезно думать и смотреть возможности применения подходящих для решения задачи инструментов.
...
Рейтинг: 0 / 0
52 сообщений из 52, показаны все 3 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Близкострочные операции
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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