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

Код: plsql
1.
2.
3.
4.
  update table1 t
      set t.field1 = f_function_1(param1 => t.field3),
          t.field2 = f_function_1(param1 => t.field3)
  where (некоторые условия) 



Смущает что приходится одну и ту же функцию вызывать дважды с одними и теми же параметрами на входе. Нельзя ли здесь как-то оптимизировать запрос? t.field2 = t.field1 понятно не прокатит. Курсор не вариант, так как выполняться будет дольше и нет полей чтбы однозначно идентифицировать отдельную запись.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390203
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t.field2 = t.field1
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390213
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав Любомудров, t.field2 = t.field1 не сработает, так как возмётся не изменённое значение t.field1 из таблицы и запишется в t.field2.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390215
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortisПривет,
что-то затруднился. Требуется выполнить обновление, установив некоторые поля в значения, возвращаемые одной функцией:

Код: plsql
1.
2.
3.
4.
  update table1 t
      set t.field1 = f_function_1(param1 => t.field3),
          t.field2 = f_function_1(param1 => t.field3)
  where (некоторые условия) 



Смущает что приходится одну и ту же функцию вызывать дважды с одними и теми же параметрами на входе. Нельзя ли здесь как-то оптимизировать запрос? t.field2 = t.field1 понятно не прокатит. Курсор не вариант, так как выполняться будет дольше и нет полей чтбы однозначно идентифицировать отдельную запись.У меня есть подобная задача. Вызов моей функции действительно стоит дорого (в ней множество точечных индексных обращений) - поэтому вместо функции я сделал вызов процедуры с out-параметрами, и решаю данную задачу в PL/SQL с помощью циклов + bulk fetch + коллекций + forall update.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390217
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortisВячеслав Любомудров, t.field2 = t.field1 не сработает, так как возмётся не изменённое значение t.field1 из таблицы и запишется в t.field2.Гоню, конечно
update (select field1, field2, f_function_1(param1 => t.field3) a where ...) set field1=a, field2=a
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390218
rigor mortis,

result cache, deterministic ?
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390224
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadrigor mortisПривет,
что-то затруднился. Требуется выполнить обновление, установив некоторые поля в значения, возвращаемые одной функцией:

Код: plsql
1.
2.
3.
4.
  update table1 t
      set t.field1 = f_function_1(param1 => t.field3),
          t.field2 = f_function_1(param1 => t.field3)
  where (некоторые условия) 



Смущает что приходится одну и ту же функцию вызывать дважды с одними и теми же параметрами на входе. Нельзя ли здесь как-то оптимизировать запрос? t.field2 = t.field1 понятно не прокатит. Курсор не вариант, так как выполняться будет дольше и нет полей чтбы однозначно идентифицировать отдельную запись.У меня есть подобная задача. Вызов моей функции действительно стоит дорого (в ней множество точечных индексных обращений) - поэтому вместо функции я сделал вызов процедуры с out-параметрами, и решаю данную задачу в PL/SQL с помощью циклов + bulk fetch + коллекций + forall update.Хотя у меня поля апдейтятся разными значениями, а у тебя одним.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390290
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, updatable view, оказывается, тоже разложится на 2 вызова
Но ведь есть еще Scalar Subquery Expression
Код: 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.
tst> create function f1(a number) return number as
  2  begin dbms_output.put_line('!!!');
  3        return 10-a;
  4  end;
  5  /

Function created.

tst> create table t1 as select rownum a, rownum+1 b, rownum+2 c from dual connect by level <= 3;

Table created.

tst> set serveroutput on
tst> update (select a, b, f1(c) y from t1 where c = 4) set a=y, b=y;
!!!
!!!

1 row updated.

tst> select * from t1;

         A          B          C
---------- ---------- ----------
         1          2          3
         6          6          4
         3          4          5

tst> rollback;

Rollback complete.

tst> update (select a, b, (select f1(c) from dual) y from t1 where c=4) set a=y, b=y;
!!!

1 row updated.

tst> select * from t1;

         A          B          C
---------- ---------- ----------
         1          2          3
         6          6          4
         3          4          5

tst> update (select a, b, (select f1(c) from dual) y from t1 where c>3) set a=y, b=y;
!!!
!!!

2 rows updated.

tst> select * from t1;

         A          B          C
---------- ---------- ----------
         1          2          3
         6          6          4
         5          5          5

...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390304
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortis,

Насколько я помню лучше всего отрабатывает связка result_cache + Scalar SQ, Т.к. result_cache еще и cross-session.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390417
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
что-то затруднилсяrigor mortis,

result cache, deterministic ?
Спасибо, deterministic подходит
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390450
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используй MERGE:

Код: 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.
drop table t1 purge
/
set serveroutput on
create or replace function f1(a number) return number as
begin dbms_output.put_line('!!!');
      return 10-a;
end;
/
create table t1 as select rownum a, rownum+1 b, rownum+2 c from dual connect by level <= 3
/
merge
  into t1 d
  using(
        select rowid rid, f1(c) y from t1 where c = 4
       ) s
  on (
      s.rid = d.rowid
     )
  when matched
    then
      update
         set a = y,
             b = y
/
!!!

1 row merged.

SQL> 



SY.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390514
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SYИспользуй MERGE:

Код: 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.
drop table t1 purge
/
set serveroutput on
create or replace function f1(a number) return number as
begin dbms_output.put_line('!!!');
      return 10-a;
end;
/
create table t1 as select rownum a, rownum+1 b, rownum+2 c from dual connect by level <= 3
/
merge
  into t1 d
  using(
        select rowid rid, f1(c) y from t1 where c = 4
       ) s
  on (
      s.rid = d.rowid
     )
  when matched
    then
      update
         set a = y,
             b = y
/
!!!

1 row merged.

SQL> 



SY.

Этот вариант что-то вообще дольше получился на порядок. А с deterministic время выполнения сократилось на 20%.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39390587
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rigor mortisЭтот вариант что-то вообще дольше получился на порядок. А с deterministic время выполнения сократилось на 20%.

Вeрсия?

11G
Код: 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.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
SQL> set timing off
SQL> set autotrace off
SQL> select banner from v$version
  2  /

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> drop table t1 purge
  2  /

Table dropped.

SQL> set serveroutput on
SQL> create or replace function f1(a number) return number as
  2  begin --dbms_output.put_line('!!!');
  3        return 10-a;
  4  end;
  5  /

Function created.

SQL> create table t1 as select rownum a, rownum+1 b, rownum+2 c from dual connect by level <= 1000000
  2  /

Table created.

SQL> set timing on
SQL> set autotrace on
SQL> merge
  2    into t1 d
  3    using(
  4          select rowid rid, f1(c) y from t1 where mod(c,10) = 0
  5         ) s
  6    on (
  7        s.rid = d.rowid
  8       )
  9    when matched
 10      then
 11        update
 12           set a = y,
 13               b = y
 14  /

100000 rows merged.

Elapsed: 00:00:04.69

Execution Plan
----------------------------------------------------------
Plan hash value: 359177147

-------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | MERGE STATEMENT      |      | 85923 |  3272K|       |  4245   (1)| 00:00:51 |
|   1 |  MERGE               | T1   |       |       |       |            |          |
|   2 |   VIEW               |      |       |       |       |            |          |
|*  3 |    HASH JOIN         |      | 85923 |  6377K|  3112K|  4245   (1)| 00:00:51 |
|*  4 |     TABLE ACCESS FULL| T1   | 85923 |  2097K|       |   768   (3)| 00:00:10 |
|   5 |     TABLE ACCESS FULL| T1   |   858K|    41M|       |   758   (2)| 00:00:10 |
-------------------------------------------------------------------------------------

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

   3 - access(ROWID="D".ROWID)
   4 - filter(MOD("C",10)=0)

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


Statistics
----------------------------------------------------------
        248  recursive calls
     102767  db block gets
       5908  consistent gets
       2759  physical reads
   26394228  redo size
       2071  bytes sent via SQL*Net to client
       1616  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
     100000  rows processed

SQL> commit
  2  /

Commit complete.

Elapsed: 00:00:00.00
SQL> update (select a, b, (select f1(c) from dual) y from t1 where mod(c,10) = 0) set a=y, b=y
  2  /

100000 rows updated.

Elapsed: 00:00:06.11

Execution Plan
----------------------------------------------------------
Plan hash value: 2212140970

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |      | 85923 |  3272K|   516K (34)| 01:43:16 |
|   1 |  UPDATE            | T1   |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 85923 |  3272K|   768   (3)| 00:00:10 |
|   3 |   FAST DUAL        |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------

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

   2 - filter(MOD("C",10)=0)

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


Statistics
----------------------------------------------------------
        102  recursive calls
     102486  db block gets
       2869  consistent gets
          0  physical reads
   25784148  redo size
       1125  bytes sent via SQL*Net to client
       1197  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     100000  rows processed

SQL> commit
  2  /

Commit complete.

Elapsed: 00:00:00.00
SQL> update t1 set a=f1(c), b=f1(c)  where mod(c,10) = 0
  2  /

100000 rows updated.

Elapsed: 00:00:09.40

Execution Plan
----------------------------------------------------------
Plan hash value: 2927627013

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |      | 85923 |  3272K|   768   (3)| 00:00:10 |
|   1 |  UPDATE            | T1   |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 85923 |  3272K|   768   (3)| 00:00:10 |
---------------------------------------------------------------------------

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

   2 - filter(MOD("C",10)=0)

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


Statistics
----------------------------------------------------------
        182  recursive calls
     204255  db block gets
       2903  consistent gets
          0  physical reads
   45903412  redo size
       1125  bytes sent via SQL*Net to client
       1156  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     100000  rows processed

SQL> commit
  2  /

Commit complete.

Elapsed: 00:00:00.01
SQL> 



Так что смотри планы и ищи в чем дело.

SY.
...
Рейтинг: 0 / 0
Как оптимизировать запрос обновления
    #39392977
rigor mortis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SYrigor mortisЭтот вариант что-то вообще дольше получился на порядок. А с deterministic время выполнения сократилось на 20%.

Вeрсия?

11G
Код: 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.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
SQL> set timing off
SQL> set autotrace off
SQL> select banner from v$version
  2  /

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> drop table t1 purge
  2  /

Table dropped.

SQL> set serveroutput on
SQL> create or replace function f1(a number) return number as
  2  begin --dbms_output.put_line('!!!');
  3        return 10-a;
  4  end;
  5  /

Function created.

SQL> create table t1 as select rownum a, rownum+1 b, rownum+2 c from dual connect by level <= 1000000
  2  /

Table created.

SQL> set timing on
SQL> set autotrace on
SQL> merge
  2    into t1 d
  3    using(
  4          select rowid rid, f1(c) y from t1 where mod(c,10) = 0
  5         ) s
  6    on (
  7        s.rid = d.rowid
  8       )
  9    when matched
 10      then
 11        update
 12           set a = y,
 13               b = y
 14  /

100000 rows merged.

Elapsed: 00:00:04.69

Execution Plan
----------------------------------------------------------
Plan hash value: 359177147

-------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | MERGE STATEMENT      |      | 85923 |  3272K|       |  4245   (1)| 00:00:51 |
|   1 |  MERGE               | T1   |       |       |       |            |          |
|   2 |   VIEW               |      |       |       |       |            |          |
|*  3 |    HASH JOIN         |      | 85923 |  6377K|  3112K|  4245   (1)| 00:00:51 |
|*  4 |     TABLE ACCESS FULL| T1   | 85923 |  2097K|       |   768   (3)| 00:00:10 |
|   5 |     TABLE ACCESS FULL| T1   |   858K|    41M|       |   758   (2)| 00:00:10 |
-------------------------------------------------------------------------------------

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

   3 - access(ROWID="D".ROWID)
   4 - filter(MOD("C",10)=0)

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


Statistics
----------------------------------------------------------
        248  recursive calls
     102767  db block gets
       5908  consistent gets
       2759  physical reads
   26394228  redo size
       2071  bytes sent via SQL*Net to client
       1616  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
     100000  rows processed

SQL> commit
  2  /

Commit complete.

Elapsed: 00:00:00.00
SQL> update (select a, b, (select f1(c) from dual) y from t1 where mod(c,10) = 0) set a=y, b=y
  2  /

100000 rows updated.

Elapsed: 00:00:06.11

Execution Plan
----------------------------------------------------------
Plan hash value: 2212140970

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |      | 85923 |  3272K|   516K (34)| 01:43:16 |
|   1 |  UPDATE            | T1   |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 85923 |  3272K|   768   (3)| 00:00:10 |
|   3 |   FAST DUAL        |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------

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

   2 - filter(MOD("C",10)=0)

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


Statistics
----------------------------------------------------------
        102  recursive calls
     102486  db block gets
       2869  consistent gets
          0  physical reads
   25784148  redo size
       1125  bytes sent via SQL*Net to client
       1197  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     100000  rows processed

SQL> commit
  2  /

Commit complete.

Elapsed: 00:00:00.00
SQL> update t1 set a=f1(c), b=f1(c)  where mod(c,10) = 0
  2  /

100000 rows updated.

Elapsed: 00:00:09.40

Execution Plan
----------------------------------------------------------
Plan hash value: 2927627013

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |      | 85923 |  3272K|   768   (3)| 00:00:10 |
|   1 |  UPDATE            | T1   |       |       |            |          |
|*  2 |   TABLE ACCESS FULL| T1   | 85923 |  3272K|   768   (3)| 00:00:10 |
---------------------------------------------------------------------------

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

   2 - filter(MOD("C",10)=0)

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


Statistics
----------------------------------------------------------
        182  recursive calls
     204255  db block gets
       2903  consistent gets
          0  physical reads
   45903412  redo size
       1125  bytes sent via SQL*Net to client
       1156  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     100000  rows processed

SQL> commit
  2  /

Commit complete.

Elapsed: 00:00:00.01
SQL> 



Так что смотри планы и ищи в чем дело.

SY.

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


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