powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Производительность update с использованием явного курсора
6 сообщений из 6, страница 1 из 1
Производительность update с использованием явного курсора
    #38599932
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

Дано: WI-V2.5.3.26726, суперклассик, коннект с кешем = 16384, FW = OFF, страница = 4096
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SQL> show version;
ISQL Version: WI-V2.5.3.26726 Firebird 2.5
Server version:
Firebird/x86/Windows NT (access method), version "WI-V2.5.3.26726 Firebird 2.5"
Firebird/x86/Windows NT (remote server), version "WI-V2.5.3.26726 Firebird 2.5/tcp (balaha)/P12"
Firebird/x86/Windows NT (remote interface), version "WI-V2.5.3.26726 Firebird 2.5/tcp (balaha)/P12"
on disk structure version 11.2

SQL> show database;
Database: localhost/3253:C:\1INSTALL\FIREBIRD\FB25SNAP\T0.fdb
        Owner: SYSDBA
PAGE_SIZE 4096
Number of DB pages allocated = 1117
Sweep interval = 20000
Forced Writes are OFF
Transaction - oldest = 3
Transaction - oldest active = 369
Transaction - oldest snapshot = 369
Transaction - Next = 376
ODS = 11.2
Default Character set: NONE

DDL:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
drop sequence g;
create sequence g;
recreate table t(id int primary key, f01 int);
commit;
delete from t;
insert into t select gen_id(g,1), gen_id(g,0)*10 from rdb$types,rdb$types
rows 20000
;
set heading off;
select count(*) from t;
commit;

Задача: записать в F01 значение из этого же столбца, но "следующей" строки в порядке возрастания ID.
То есть, для набора:
Код: plaintext
1.
2.
3.
4.
5.
6.
 ID          F01
=== ============
  1           10
  2           20
  3           30
  4           40
. . .
должно получиться:
Код: plaintext
1.
2.
3.
4.
5.
6.
 ID          F01
=== ============
  1           20
  2           30
  3           40
  4           50
. . .
(в последней строке F01 будет NULL).


var-1 Через SQL, тупо в лоб:
12738 ms
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
update t a set f01 = (select f01 from t x where x.id>a.id order by id rows 1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY30 INDEX (RDB$PRIMARY30))
PLAN (A NATURAL)
0 records fetched
   12738 ms , 1 write(s), 644931 fetch(es), 48792 mark(s)

Table                             Natural     Index    Update    Insert    Delete
*********************************************************************************
RDB$INDICES                                       2
T                                   20000     39973     20000
var-2 . Через PSQL, неявным for-курсором с апдейтом полученной записи по её ID 'шнику:
13497 ms
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
execute block as
  declare v_next_f01 int;
  declare v_id int;
begin
  for
  select id,(select f01 from t x where x.id>a.id order by id rows 1)
  from t a
  into v_id, :v_next_f01
  do update t set f01 = :v_next_f01 where id = :v_id;
end

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY24 INDEX (RDB$PRIMARY24))
PLAN (T INDEX (RDB$PRIMARY24))
PLAN (A NATURAL)
0 records fetched
   13497 ms , 1 write(s), 744955 fetch(es), 48792 mark(s)

Table                             Natural     Index    Update    Insert
************************************************************************
RDB$INDICES                                       2
T                                   20000     59973     20000
var-3. Через PSQL, неявным for-курсором с апдейтом полученной записи по её RDB$DB_KEY : судя по статистике, это близнец прямого апдейта (см выше var-1). Хотя в статистике показано на 20'000 индексных чтений больше, чем у "pure-SQL" апдейта
12132 ms
Код: plaintext
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.
execute block as
  declare v_key char(8);
  declare v_next_f01 int;
  declare v_next_id int;
begin
  for
  select rdb$db_key, (select f01 from t x where x.id>a.id order by id rows 1)
  from t a
  into :v_key, :v_next_f01
  do update t set f01 = :v_next_f01 where rdb$db_key = :v_key;
end


^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY26 INDEX (RDB$PRIMARY26))
PLAN (T INDEX ())
PLAN (A NATURAL)

0 records fetched

   12132 ms , 1 write(s), 684931 fetch(es), 48792 mark(s)



Table                             Natural     Index    Update    Insert    Delete

***********************************************************************************

RDB$INDICES                                       2

T                                   20000     59973     20000
var-4. Через PSQL, используя явный курсор + апдейт с where current of <cursor>. Капздец, 200 млн IR'ов:
689480 ms
Код: plaintext
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.
execute block as
  declare c_cur cursor for (select (select f01 from t x where x.id>a.id order by id rows 1) from t a);
  declare v_next_f01 int;
begin
  open c_cur;
  while (1=1) do
  begin
    fetch c_cur into v_next_f01;
    if (row_count = 0) then leave;
    update t set f01 = :v_next_f01 where current of c_cur;
  end
  close c_cur;
end


^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY29 INDEX (RDB$PRIMARY29))
PLAN (A NATURAL)
PLAN (X ORDER RDB$PRIMARY29)

0 records fetched

 689480 ms, 1 write(s), 600541233 fetch(es), 48792 mark(s)



Table                             Natural     Index    Update    Insert    Delete   Backout     Purge

********************************************************************************************************

RDB$INDICES                                       2

T                                   20000 200029999     20000
var-5. Через PSQL, используя явный курсор + апдейт с RDB$DB_KEY вместо "where current of <cursor>". То же самое.
643594 ms
Код: plaintext
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.
Statement 184:
-------------------------------------------------------------------------------
execute block as
  declare v_key char(8);
  declare c_cur cursor for (select a.rdb$db_key, (select f01 from t x where x.id>a.id order by id rows 1) from t a);
  declare v_next_f01 int;
begin
  open c_cur;
  while (1=1) do
  begin
    fetch c_cur into v_key, v_next_f01;
    if (row_count = 0) then leave;
    update t set f01 = :v_next_f01 where rdb$db_key = :v_key;
  end
  close c_cur;
end

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY31 INDEX (RDB$PRIMARY31))
PLAN (A NATURAL)
PLAN (X ORDER RDB$PRIMARY31)
PLAN (T INDEX ())
0 records fetched
 643594 ms, 1 write(s), 600581233 fetch(es), 48792 mark(s)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   Expunge
***************************************************************************************************************
RDB$INDICES                                       2
T                                   20000 200049999     20000

Явные курсоры с апдейтами - вещи плохо совместимые, что ле ? Откудова там это дикое число IR'ов ?
...
Рейтинг: 0 / 0
Производительность update с использованием явного курсора
    #38599941
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на тройке не пробовал?
...
Рейтинг: 0 / 0
Производительность update с использованием явного курсора
    #38599948
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrна тройке не пробовал?запустил на серваке:

Код: plaintext
1.
2.
3.
4.
5.
LI-T3.0.0.30981, SuperServer 
DefaultDbCachePages = 512K
FileSystemCacheThreshold = 65536K
TempBlockSize = 100M
TempCacheLimit = 1024M

- та же печалька, на 4-м и 5-м вариантах:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
execute block as
  declare c_cur cursor for (select (select f01 from t x where x.id>a.id order by id rows 1) from t a);
  declare v_next_f01 int;
begin
  open c_cur;
  while (1=1) do
  begin
    fetch c_cur into v_next_f01;
    if (row_count = 0) then leave;
    update t set f01 = :v_next_f01 where current of c_cur;
  end
  close c_cur;
end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY303)
PLAN (A NATURAL)
PLAN (X ORDER RDB$PRIMARY303)
0 records fetched
 239629 ms, 600532453 fetch(es), 40178 mark(s)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   
********************************************************************************************************
RDB$INDICES                                       2
T                                   20000 200029999     20000
...
Рейтинг: 0 / 0
Производительность update с использованием явного курсора
    #38599950
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пардон, 5-й вариант забыл:
Код: plaintext
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.
execute block as
  declare v_key char(8);
  declare c_cur cursor for (select a.rdb$db_key, (select f01 from t x where x.id>a.id order by id rows 1) from t a);
  declare v_next_f01 int;
begin
  open c_cur;
  while (1=1) do
  begin
    fetch c_cur into v_key, v_next_f01;
    if (row_count = 0) then leave;
    update t set f01 = :v_next_f01 where rdb$db_key = :v_key;
  end
  close c_cur;
end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (X ORDER RDB$PRIMARY304)
PLAN (A NATURAL)
PLAN (X ORDER RDB$PRIMARY304)
PLAN (T INDEX ())
0 records fetched
 242459 ms, 600572453 fetch(es), 40178 mark(s)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   Expunge
***************************************************************************************************************
RDB$INDICES                                       2
T                                   20000 200049999     20000
...
Рейтинг: 0 / 0
Производительность update с использованием явного курсора
    #38599959
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
занесешь в трекер? Я вроде понимаю, в чем там проблема, но исправить быстро не обещаю.
...
Рейтинг: 0 / 0
Производительность update с использованием явного курсора
    #38599966
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrзанесешь в трекер? Занёс.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Производительность update с использованием явного курсора
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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