powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Прошу помощи в ускорении запроса (поиск соседа)
14 сообщений из 14, страница 1 из 1
Прошу помощи в ускорении запроса (поиск соседа)
    #39371806
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приветствую!



Таблица

в базе имеется таблица AUFTRAG.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table Auftrag (
       ID                   integer NOT NULL,
       ORDER_ID_UNIQ        integer NOT NULL,
       ...
       constraint XPKAuftrag primary key (ID)
);

create unique index AUFTRAG_ORDER_ID_UNIQ
on Auftrag (ORDER_ID_UNIQ desc);


и исторически сложилось, что сортировка по полю ID не дает сортировку по времени, по-этому добавили дополнительное поле ОRDER_ID_UNIQ.


Проблема

В программе необходимо находить ID ближайшего по шкале ORDER_ID_UNIQ от заданного :ID
Вот мой запрос, который я прошу вас помочь мне ускорить (их 2, но говорю как об одном, т.к. они похожи):

Код: 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.
-- это поиск ближайшего ID в сторону уменьшения ORDER_ID_UNIQ
select ID as FOUND_ID
from AUFTRAG
where ORDER_ID_UNIQ =
(
   select max(ORDER_ID_UNIQ)
   from AUFTRAG
   where ORDER_ID_UNIQ<
   (
      select ORDER_ID_UNIQ
      from AUFTRAG
      where ID=:ID
   )
);

-- это поиск ближайшего ID в сторону увеличения ORDER_ID_UNIQ
select ID as FOUND_ID
from AUFTRAG
where ORDER_ID_UNIQ =
(
   select min(ORDER_ID_UNIQ)
   from AUFTRAG
   where ORDER_ID_UNIQ>
   (
      select ORDER_ID_UNIQ
      from AUFTRAG
      where ID=:ID
   )
);



Планы обоих запросов одинаковые (смотри ниже).


Ваши советы?
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39371808
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сорри, колонки без заголовков
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39371901
ORA__SQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён, убери desc, получишь INDEX RANGE SCAN (MIN/MAX)
Код: plsql
1.
2.
create unique index AUFTRAG_ORDER_ID_UNIQ
on Auftrag (ORDER_ID_UNIQ desc);
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39371985
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо, начинаю проверку
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39371994
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на тестовой машине помогло, на боевой только вечером получится проверить
Спасибо
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372279
Jafa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как вариант, если ORDER_ID_UNIQ без больших пропусков, можно попробовать оценить стоимость такого извращения, для 11gR2 и выше:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
WITH ForId(ORDER_ID_UNIQ) AS
(
  SELECT ORDER_ID_UNIQ FROM AUFTRAG WHERE id = :ID
  UNION ALL
  SELECT ORDER_ID_UNIQ + 1 FROM ForId 
  WHERE NOT EXISTS 
      (
          SELECT * 
          FROM AUFTRAG tmp 
          WHERE tmp.ORDER_ID_UNIQ = ForId.ORDER_ID_UNIQ + 1
      ) 
  AND ORDER_ID_UNIQ < 10000000000
),
Next_ORDER_ID_UNIQ(ORDER_ID_UNIQ) AS (SELECT COUNT(*) + (SELECT ORDER_ID_UNIQ FROM AUFTRAG WHERE id = :ID) AS ORDER_ID_UNIQ FROM ForId)
SELECT * FROM AUFTRAG WHERE AUFTRAG.ORDER_ID_UNIQ = (SELECT ORDER_ID_UNIQ FROM Next_ORDER_ID_UNIQ);
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372321
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён
-- это поиск ближайшего ID в сторону уменьшения ORDER_ID_UNIQ

-- это поиск ближайшего ID в сторону увеличения ORDER_ID_UNIQ


Код: 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.
SQL> create unique index auftrag_idx1
  2    on auftrag(order_id_uniq,id)
  3  /

Index created.

SQL> explain plan for
  2  with t as (
  3             select  id,
  4                     lag(id) over(order by order_id_uniq) found_id_prior,
  5                     lead(id) over(order by order_id_uniq) found_id_next
  6             from  auftrag
  7            )
  8  select  found_id_prior
  9          found_id_next
 10    from  t
 11    where t.id = :id
 12  /

Explained.

SQL> select * from table(dbms_xplan.display)
  2  /

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------

Plan hash value: 415877825

----------------------------------------------------------------------------------
| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |              |     1 |    26 |     1   (0)| 00:00:01 |
|*  1 |  VIEW             |              |     1 |    26 |     1   (0)| 00:00:01 |
|   2 |   WINDOW BUFFER   |              |     1 |    26 |     1   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN| AUFTRAG_IDX1 |     1 |    26 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------

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

   1 - filter("T"."ID"=TO_NUMBER(:ID))

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

19 rows selected.

SQL>



SY.
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372332
Jafa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY, я так понял, что ему нужно next or prior по order_id_uniq, а не по id
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372346
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JafaSY, я так понял, что ему нужно next or prior по order_id_uniq, а не по id

Код: plsql
1.
2.
  4                     lag(id) over(order by order_id_uniq) found_id_prior,
  5                     lead(id) over(order by order_id_uniq) found_id_next



SY.
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372369
Jafa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY, извиняюсь, все правильно
опробовал оба варианта, с рекурсивным запросом и аналитическими ф-циями на таблице с 300000 записей. И так, создаю таблицу AUFTRAG и заполняю ее записями до 300000:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create table AUFTRAG(id number primary key, ORDER_ID_UNIQ number unique);
/
insert into AUFTRAG 
(
  select rownum, l
    from 
    (
        select l from
        (
          select rownum + 300000 l
          from dual
          connect by level < (300000-0)
        ) 
        order by dbms_random.random
    )
    where rownum <= 300000
); 
commit;


тестирую варианит с аналитическими ф-ми:
Код: 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.
explain plan for
with t as (
               select  id,
                       lead(id) over(order by order_id_uniq) found_id_next
               from  auftrag
              )
    select  found_id_next
     from  t
     where t.id = :id;
/
select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1735091813                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                            
---------------------------------------------------------------------------------------                                                                                                                                                                                                                     
| Id  | Operation           | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                                                                                                                                                                                                                     
---------------------------------------------------------------------------------------                                                                                                                                                                                                                     
|   0 | SELECT STATEMENT    |         |   299K|  7617K|       |  1371   (1)| 00:00:01 |                                                                                                                                                                                                                     
|*  1 |  VIEW               |         |   299K|  7617K|       |  1371   (1)| 00:00:01 |                                                                                                                                                                                                                     
|   2 |   WINDOW SORT       |         |   299K|  2929K|  5896K|  1371   (1)| 00:00:01 |                                                                                                                                                                                                                     
|   3 |    TABLE ACCESS FULL| AUFTRAG |   299K|  2929K|       |   171   (1)| 00:00:01 |                                                                                                                                                                                                                     
---------------------------------------------------------------------------------------                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                            

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):                                                                                                                                                                                                                                                         
---------------------------------------------------                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                                                            
   1 - filter("T"."ID"=TO_NUMBER(:ID))                                                                                                                                                                                                                                                                      

 15 rows selected 


тестирую вариант с рекурсией
Код: 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.
WITH ForId(ORDER_ID_UNIQ) AS
(
  SELECT ORDER_ID_UNIQ FROM AUFTRAG WHERE id = :id
  UNION ALL
  SELECT ORDER_ID_UNIQ + 1 FROM ForId 
  WHERE NOT EXISTS 
      (
          SELECT * 
          FROM AUFTRAG tmp 
          WHERE tmp.ORDER_ID_UNIQ = ForId.ORDER_ID_UNIQ + 1
      ) 
  AND ORDER_ID_UNIQ < 10000000000000000000000
),
Next_ORDER_ID_UNIQ(ORDER_ID_UNIQ) AS (SELECT cnt + (SELECT ORDER_ID_UNIQ FROM AUFTRAG WHERE id = :id) AS ORDER_ID_UNIQ FROM (SELECT COUNT(ORDER_ID_UNIQ) AS cnt FROM ForId))
SELECT * FROM AUFTRAG WHERE AUFTRAG.ORDER_ID_UNIQ = (SELECT ORDER_ID_UNIQ FROM Next_ORDER_ID_UNIQ);
/
select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 232072449                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                            
--------------------------------------------------------------------------------------------------------------                                                                                                                                                                                              
| Id  | Operation                                     | Name         | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                              
--------------------------------------------------------------------------------------------------------------                                                                                                                                                                                              
|   0 | SELECT STATEMENT                              |              |     1 |    10 |     3   (0)| 00:00:01 |                                                                                                                                                                                              
|   1 |  TABLE ACCESS BY INDEX ROWID                  | AUFTRAG      |     1 |    10 |     3   (0)| 00:00:01 |                                                                                                                                                                                              
|*  2 |   INDEX UNIQUE SCAN                           | SYS_C0011306 |     1 |       |     2   (0)| 00:00:01 |                                                                                                                                                                                              
|   3 |    VIEW                                       |              |     1 |    13 |     6   (0)| 00:00:01 |                                                                                                                                                                                              
|   4 |     SORT AGGREGATE                            |              |     1 |    13 |            |          |                                                                                                                                                                                              
|   5 |      VIEW                                     |              |     2 |    26 |     6   (0)| 00:00:01 |                                                                                                                                                                                              

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   6 |       UNION ALL (RECURSIVE WITH) BREADTH FIRST|              |       |       |            |          |                                                                                                                                                                                              
|   7 |        TABLE ACCESS BY INDEX ROWID            | AUFTRAG      |     1 |    10 |     2   (0)| 00:00:01 |                                                                                                                                                                                              
|*  8 |         INDEX UNIQUE SCAN                     | SYS_C0011305 |     1 |       |     1   (0)| 00:00:01 |                                                                                                                                                                                              
|*  9 |        FILTER                                 |              |       |       |            |          |                                                                                                                                                                                              
|* 10 |         RECURSIVE WITH PUMP                   |              |       |       |            |          |                                                                                                                                                                                              
|* 11 |         INDEX UNIQUE SCAN                     | SYS_C0011306 |     1 |     5 |     2   (0)| 00:00:01 |                                                                                                                                                                                              
|  12 |    TABLE ACCESS BY INDEX ROWID                | AUFTRAG      |     1 |    10 |     2   (0)| 00:00:01 |                                                                                                                                                                                              
|* 13 |     INDEX UNIQUE SCAN                         | SYS_C0011305 |     1 |       |     1   (0)| 00:00:01 |                                                                                                                                                                                              
--------------------------------------------------------------------------------------------------------------                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                            
Predicate Information (identified by operation id):                                                                                                                                                                                                                                                         

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                                                            
   2 - access("AUFTRAG"."ORDER_ID_UNIQ"= (SELECT "CNT"+ (SELECT "ORDER_ID_UNIQ" FROM "AUFTRAG"                                                                                                                                                                                                              
              "AUFTRAG" WHERE "ID"=TO_NUMBER(:ID)) FROM  (SELECT COUNT("ORDER_ID_UNIQ") "CNT" FROM "FORID" "FORID")                                                                                                                                                                                         
              "from$_subquery$_005"))                                                                                                                                                                                                                                                                       
   8 - access("ID"=TO_NUMBER(:ID))                                                                                                                                                                                                                                                                          
   9 - filter( NOT EXISTS (SELECT 0 FROM "AUFTRAG" "TMP" WHERE "TMP"."ORDER_ID_UNIQ"=:B1+1))                                                                                                                                                                                                                
  10 - filter("ORDER_ID_UNIQ"<10000000000000000000000)                                                                                                                                                                                                                                                      
  11 - access("TMP"."ORDER_ID_UNIQ"=:B1+1)                                                                                                                                                                                                                                                                  
  13 - access("ID"=TO_NUMBER(:ID))                                                                                                                                                                                                                                                                          

 32 rows selected 


еще раз напомню, что вариант с рекурсией имеет результат хороший, если ORDER_ID_UNIQ не имеет больших пустот.
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372374
Jafa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S. после инсерта в AUFTRAG выполнил
Код: plsql
1.
execute dbms_stats.gather_table_stats(user, 'AUFTRAG', method_opt=>'for all indexed columns');
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372399
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
12c:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select  found_id_next
  from  auftrag
  match_recognize(
                  order by order_id_uniq
                  measures id as found_id_next
                  pattern(up)
                  define
                    up as prev(id) = :id
                 )
/



Правда неясно как оценить MATCH RECOGNIZE SORT DETERMINISTIC FINITE AUTOMATON.

SY.
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372405
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jafaоценить стоимость такого извращенияRec with при данной постановке, да, это изврещение. Хорошо что ты это признаешь.
SYПравда неясно как оценить MATCH RECOGNIZE SORT DETERMINISTIC FINITE AUTOMATON.Ребята, вы увлеклись какими-то попугаями не обращая внимания на изначальную постановку.
Кроик СемёнВот мой запрос, который я прошу вас помочь мне ускорить
Использование аналитики или паттерн матчинга и полного сканирования (индекса) - это даже не смешно.

PS. Про FINITE AUTOMATON это не сакральные знания и легко находится поиском.
MATCH_RECOGNIZE and the Optimizer и т.д.
...
Рейтинг: 0 / 0
Прошу помощи в ускорении запроса (поиск соседа)
    #39372413
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop,

Ну так ему-же ora_sql и предлoжил MIN/MAX. А мы так, пoбаловаться. А насчет MATCH RECOGNIZE SORT DETERMINISTIC FINITE AUTOMATON вопрос был не что это такое а как это оценить при сравнении например с SQL возвращающим тот жe результат через аналитику или агрегацию или рекурсию...

SY.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Прошу помощи в ускорении запроса (поиск соседа)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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