powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Еще раз о ramdisk
47 сообщений из 47, показаны все 2 страниц
Еще раз о ramdisk
    #38562224
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
FB 2.5.

База FW=OFF

В одной таблице 4 477 968 записей. нужно перекачать их в соседнюю таблицу похожей структуры.
Решил проверить будет ли быстрее работа на ramdisk. Оказалось что на ramdisk экономия всего 24%.


CREATE TABLE RCP_RAW_QLT (
RCPREP_ID ID,
QLT_ID ID,
QLT_VAL REAL_WNULL,
VALUE_IN_DM REAL_WNULL,
VALUE_NATIVE REAL_WNULL,
VALUE_PREMIX REAL_WNULL,
CONSTRAINT PK_RCP_RAW_QLT PRIMARY KEY (RCPREP_ID, QLT_ID),
CONSTRAINT FK_RCP_RAW_QLT_QLT_ID FOREIGN KEY (QLT_ID) REFERENCES QM_DICT (QLT_ID),
CONSTRAINT FK_RCP_RAW_QLT_RCPREP_ID FOREIGN KEY (RCPREP_ID) REFERENCES RCPREP (RCPREP_ID) ON DELETE CASCADE
);

запрос

insert into RCP_RAW_QLT (RCPREP_ID, QLT_ID, QLT_VAL, VALUE_NATIVE, VALUE_PREMIX)
select RR.RCPREP_ID, RQ.QLT_ID, RQ.QLT_VAL, RQ.VALUE_NATIVE, RQ.VALUE_PREMIX
from RCPREP RR
join RCPRQLT RQ on RR.RCP_ID = RQ.RCP_ID and
RR.RAW_ID = RQ.RAW_ID;

RAM 2.23 минуты
Query Time
------------------------------------------------
Prepare : 16,00 ms
Execute : 142 195,00 ms
Avg fetch time: 0,00 ms

Memory
------------------------------------------------
Current: 262 186 112
Max : 264 527 168
Buffers: 60 480

Operations
------------------------------------------------
Read : 85 882
Writes : 135 689
Fetches: 136 491 901
Marks : 18 418 925

HDD 2.56 минуты

Query Time
------------------------------------------------
Prepare : 16,00 ms
Execute : 176 749,00 ms
Avg fetch time: 0,00 ms

Memory
------------------------------------------------
Current: 262 186 956
Max : 264 528 436
Buffers: 60 480

Operations
------------------------------------------------
Read : 85 881
Writes : 270 810
Fetches: 136 491 901
Marks : 18 486 521
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562229
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77CREATE TABLE RCP_RAW_QLT (
RCPREP_ID ID,
QLT_ID ID,
QLT_VAL REAL_WNULL,
VALUE_IN_DM REAL_WNULL,
VALUE_NATIVE REAL_WNULL,
VALUE_PREMIX REAL_WNULL,
CONSTRAINT PK_RCP_RAW_QLT PRIMARY KEY (RCPREP_ID, QLT_ID),
CONSTRAINT FK_RCP_RAW_QLT_QLT_ID FOREIGN KEY (QLT_ID) REFERENCES QM_DICT (QLT_ID),
CONSTRAINT FK_RCP_RAW_QLT_RCPREP_ID FOREIGN KEY (RCPREP_ID) REFERENCES RCPREP (RCPREP_ID) ON DELETE CASCADE

);Констрейнты на target-таблице можете временно drop, а после инсертов add ? если да, то попробуйте.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562232
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS. Если констрейнты на target-таблице заглушать нельзя, покажите значение параметра TempCacheLimit. Судя по PK = (RCPREP _ID , QLT _ID ), для создания этого индекса "внутри" TempCacheLimit'a надо установить его не менее 4500000 * (20 + 4 +4 ) = ~126 Mb.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562368
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТаблоидPS. Если констрейнты на target-таблице заглушать нельзя, покажите значение параметра TempCacheLimit. Судя по PK = (RCPREP _ID , QLT _ID ), для создания этого индекса "внутри" TempCacheLimit'a надо установить его не менее 4500000 * (20 + 4 +4 ) = ~126 Mb.

Спасибо за рекомендации. Но вопрос у меня чисто риторический.
Задача не практическая, а тестовая.
Почему выигрыш ramdiska на данной операции всего 25%. TempDir кстати тоже на ramdisk.
Я ожидал большего.
Получается в этой задаче мы упираемся в производительность самого сервера (чисто процессорная задача).
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562373
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77ТаблоидPS. Если констрейнты на target-таблице заглушать нельзя, покажите значение параметра TempCacheLimit. Судя по PK = (RCPREP _ID , QLT _ID ), для создания этого индекса "внутри" TempCacheLimit'a надо установить его не менее 4500000 * (20 + 4 +4 ) = ~126 Mb.

Спасибо за рекомендации. Но вопрос у меня чисто риторический.
Задача не практическая, а тестовая.
Почему выигрыш ramdiska на данной операции всего 25%. TempDir кстати тоже на ramdisk.
Я ожидал большего.
Получается в этой задаче мы упираемся в производительность самого сервера (чисто процессорная задача).Вы не показали свой TempCacheLimit.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562377
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТаблоидВы не показали свой TempCacheLimit.
Стандартный.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562378
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bazilio77ТаблоидВы не показали свой TempCacheLimit.
Стандартный.
Кстати при чем тут TempCacheLimit если и база и TempDir находятся на ramdiske
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562382
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТаблоидВы не показали свой TempCacheLimit.
Сделал TempCacheLimit 250 Мб. Ничего не поменялось Время 2:21.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562383
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77ТаблоидВы не показали свой TempCacheLimit.
Сделал TempCacheLimit 250 Мб. Ничего не поменялось Время 2:21.
А загрузка ядра процессора какая?
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562386
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77Стандартный.Он разный для SS (64 М) vs SC/CS (8M).
bazilio77Кстати при чем тут TempCacheLimit если и база и TempDir находятся на ramdiskeКогда движку не хватает TempCacheLimit, он начинает выталкивать данные на диск, в каталог, заданный параметром TempDirs. ДАЖЕ ЕСЛИ В СИСТЕМЕ ЕЩЕ ПОЛНО ПАМЯТИ. В виндузе это видно просмотром соотв. каталога, в линухе - командой lsof -a +L1 <temp_folder_mount_point>: там появляются и растут времянки.

Ну так вот: даже если параметр TempDirs указывает на ram-диск, обмен между "внутренней" памятью, которая была зарезервирована под TCL, и "наружней", настолько затратен, что там почти без разницы, жесткий это диск или ram. Совсем недавно я напоролся как раз на это, вот тынц .
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562389
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77Почему выигрыш ramdiska на данной операции всего 25%
потому что FW=OFF
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562391
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидКогда движку не хватает TempCacheLimit, он начинает выталкивать данные на диск, в каталог, заданный параметром TempDirs. ДАЖЕ ЕСЛИ В СИСТЕМЕ ЕЩЕ ПОЛНО ПАМЯТИ.
вот любишь ты по результатам пары экспериментов обобщенные выводы делать...
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562393
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТаблоидКогда движку не хватает TempCacheLimit, он начинает выталкивать данные на диск, в каталог, заданный параметром TempDirs. ДАЖЕ ЕСЛИ В СИСТЕМЕ ЕЩЕ ПОЛНО ПАМЯТИ.
вот любишь ты по результатам пары экспериментов обобщенные выводы делать...Но ведь ФБ не будет оттяпывать себе еще памяти под темпспейс, если TCL исчерпан ?
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562398
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

не будет. Но пишет он в кеш файловой системы, так что СВОБОДНАЯ ПАМЯТЬ В СИСТЕМЕ ТАКИ БУДЕТ ИСПОЛЬЗОВАТЬСЯ.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562401
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrне будет. Но пишет он в кеш файловой системы, так что СВОБОДНАЯ ПАМЯТЬ В СИСТЕМЕ ТАКИ БУДЕТ ИСПОЛЬЗОВАТЬСЯ.да, но я *сразу* после старта видел fb_* файлы в tempfs или в /tmp (когда TCL был мал) - это что получается, сама операционка их начинала записывать ?
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562402
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидда, но я *сразу* после старта видел fb_* файлы в tempfs или в /tmp (когда TCL был мал) - это что получается, сама операционка их начинала записывать ?
они создаются сразу по исчерпании TCL, с нулевым размером. А вот писать туда ось начинает отнюдь не сразу. И уж тем более читает из своего кеша, а не с диска.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562472
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Резюме: FW=OFF при достаточном кэше нисколько не проигравыет ramdisk.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562491
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77,

во-первых, только при установленных в -1 параметрах MaxUnflushed* в конфиге. Во-вторых, все-таки проигрывает, пусть и немного.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562569
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrвсе-таки проигрывает, пусть и немного.на линухе при следующих изменённых параметрах конфига (NB: DefaultDBCachePages = 2048; арх-ра = SuperClassic; версия = LI-T3.0.0.30876):
Код: plaintext
1.
2.
3.
4.
FileSystemCacheThreshold = 65536K
RemoteServicePort = 3333
TempBlockSize = 67108864
TempCacheLimit = 1073741824
TempDirectories = /dev/shm;/tmp

- и вставке 5 млн строк в таблицу c последующим их удалением, картина следующая:
DDL:
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
recreate table t(id int primary key, s01 varchar(36), s02 varchar(36), s03 varchar(36) );
commit;
create index t_s01 on t(s01);
create index t_s02 on t(s02);
create index t_s03 on t(s03);
commit;
set term ^;
execute block as
begin
  begin
    execute statement 'create sequence g';
    when any do begin end
  end
end^
set term ;^
commit;
alter sequence g restart with 0;
commit;

-- 1'000'000 ==> 352 Mb
-- 5'000'000 ==> 1700Mb, ~7 min
set stat on;
set term ^;
execute block as
  declare n int = 5000000;
begin
  while (n>0) do
    insert into t(id, s01, s02, s03)
    values( :n +iif( mod(:n,1000)=0, 0*gen_id(g,1000), 0),
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid())
          ) returning :n-1 into n;
end^
set term ;^

set echo on;

commit;
select count(*) from t;
delete from t;
commit;
set echo off;
show version;
show database;
set echo on;
exit;
1. FW = OFF, база создана на ram-диске /dev/shm: ins = 381.75", del=11.78"
log
Код: 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.
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.
$ /opt/fb30trnk/bin/isql -q
SQL> create database 'tmpram.fdb';
SQL> quit;

$ /opt/fb30trnk/bin/gfix -w async /dev/shm/tmpram.fdb

$ /opt/fb30trnk/bin/gstat -h tmpram.fdb |grep -i attributes
        Attributes

$ /opt/fb30trnk/bin/isql localhost/3333:/dev/shm/tmpram.fdb
Database:  localhost/3333:/dev/shm/tmpram.fdb

SQL> in /var/db/fb30/instest.sql;
Current memory = 12594992
Delta memory = 206248
Max memory = 17706016
Elapsed time= 381.750 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 20827420
Writes = 15445615
Fetches = 111122956

commit;
Current memory = 12520344
Delta memory = -74648
Max memory = 17706016
Elapsed time= 0.004 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 1
Writes = 1106
Fetches = 2
select count(*) from t;

                COUNT
=====================
              5000000

Current memory = 12557232
Delta memory = 25800
Max memory = 17706016
Elapsed time= 3.134 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 200440
Writes = 0
Fetches = 10400445

delete from t;
Current memory = 12659296
Delta memory = 102064
Max memory = 17770280
Elapsed time= 11.779 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 200448
Writes = 198001
Fetches = 25400488

commit;
Current memory = 12633744
Delta memory = -25552
Max memory = 17770280
Elapsed time= 0.006 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 1
Writes = 2001
Fetches = 2

set echo off;
ISQL Version: LI-T3.0.0.30876 Firebird 3.0 Alpha 2
Server version:
Firebird/Linux/AMD/Intel/x64 (access method), version "LI-T3.0.0.30876 Firebird 3.0 Alpha 2"
Firebird/Linux/AMD/Intel/x64 (remote server), version "LI-T3.0.0.30876 Firebird 3.0 Alpha 2/tcp (oel64)/P13"
Firebird/Linux/AMD/Intel/x64 (remote interface), version "LI-T3.0.0.30876 Firebird 3.0 Alpha 2/tcp (oel64)/P13"
on disk structure version 12.0
Database: localhost/3333:/dev/shm/tmpram.fdb
        Owner: SYSDBA
PAGE_SIZE 4096
Number of DB pages allocated = 435904
Sweep interval = 20000
Forced Writes are OFF
Transaction - oldest = 22
Transaction - oldest active = 23
Transaction - oldest snapshot = 23
Transaction - Next = 24
ODS = 12.0
Default Character set: NONE
exit;
2. FW = OFF, база создана на hdd-диске, в каталоге /tmp: ins=443.78", del=11.89"
log
Код: 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.
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.
$ /opt/fb30trnk/bin/isql -q
SQL> create database '/tmp/tmphdd.fdb';
SQL> quit;

$ /opt/fb30trnk/bin/gfix -w async /tmp/tmphdd.fdb


$ /opt/fb30trnk/bin/gstat -h /tmp/tmphdd.fdb | grep -i attributes
        Attributes


$ /opt/fb30trnk/bin/isql localhost/3333:/tmp/tmphdd.fdb -i /var/db/fb30/instest.sql
Current memory = 12594984
Delta memory = 206248
Max memory = 17706008
Elapsed time= 443.738 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 20826670
Writes = 15444747
Fetches = 111069310

commit;
Current memory = 12520336
Delta memory = -74648
Max memory = 17706008
Elapsed time= 0.025 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 1
Writes = 1129
Fetches = 2

select count(*) from t;

                COUNT
=====================
              5000000

Current memory = 12557224
Delta memory = 25800
Max memory = 17706008
Elapsed time= 3.191 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 200440
Writes = 0
Fetches = 10400445

delete from t;
Current memory = 12659288
Delta memory = 102064
Max memory = 17770272
Elapsed time= 11.895 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 200448
Writes = 198056
Fetches = 25400488

commit;
Current memory = 12633736
Delta memory = -25552
Max memory = 17770272
Elapsed time= 0.007 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 1
Writes = 1946
Fetches = 2

set echo off;
ISQL Version: LI-T3.0.0.30876 Firebird 3.0 Alpha 2
Server version:
Firebird/Linux/AMD/Intel/x64 (access method), version "LI-T3.0.0.30876 Firebird 3.0 Alpha 2"
Firebird/Linux/AMD/Intel/x64 (remote server), version "LI-T3.0.0.30876 Firebird 3.0 Alpha 2/tcp (oel64)/P13"
Firebird/Linux/AMD/Intel/x64 (remote interface), version "LI-T3.0.0.30876 Firebird 3.0 Alpha 2/tcp (oel64)/P13"
on disk structure version 12.0
Database: localhost/3333:/tmp/tmphdd.fdb
        Owner: SYSDBA
PAGE_SIZE 4096
Number of DB pages allocated = 435776
Sweep interval = 20000
Forced Writes are OFF
Transaction - oldest = 22
Transaction - oldest active = 23
Transaction - oldest snapshot = 23
Transaction - Next = 24
ODS = 12.0
Default Character set: NONE
exit;

Вставки выигрывают примерно на 16%.
Удаления и подсчет числа записей, как видно, остались одинаковыми.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562572
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0xFF.
Когда вставка идёт в индексированную GTT, то было бы круто обновлять её индексы НЕ на каждой записи, а после окончания обработки "входного потока". Т.е. пока идёт заливка строк с 1-ой по 100499-ю - плевать на индексы, оставляем их в "несоответствующем" (новым данным) виде.
/* Роллбак посередине случился - тем лучше, меньше откатывать надо (для gtt on commit preserve rows).
Авария хоста - вообще по барабану, GTT и не должны при этом ничего сохранять. */
Когда же заканчивается добавление 100500-ой строки - обновляем все индексы на основе новых данных. Есть смутное сомнение, что так будет быстрее, чем сейчас.
Да, я помню прекрасно, что "в GTT сделано почти всё также, как в fixed-таблицах", ибо времени было в обрез и проч. Это я просто высказал идею на будущее, чтобы в воздухе не растворилась... :-)
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562580
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидКогда вставка идёт в индексированную GTT, то было бы круто обновлять её индексы НЕ на каждой записи, а после окончания обработки "входного потока". Т.е. пока идёт заливка строк с 1-ой по 100499-ю - плевать на индексы, оставляем их в "несоответствующем" (новым данным) виде.А что такое "входной поток" ? Где он начинается и где заканчивается ?
И где найти ключи от всего только что вставленного "потока" ? Перечитывать 100500 записей ? Или копить всё в (резиновой) памяти по ходу вставок ?
За контроль уникальности я даже не заикаюсь.
При чём тут вообще GTT\не GTT ???
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562584
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

насколько я в курсе, сейчас можно либо обновить один ключ, либо построить все ключи по всем записям, и пофиг это ГТТ или нет.
для "отложенного до-индексирования" все равно пришлось бы целиком сканировать таблицу, проверяя, есть уже такие ключи, или нет. Хотя, по идее, "достроить" ключи быстрее, чем целиком перестроить весь индекс. Но такого механизма все равно (пока) нет.
И он достаточно опасен. Например, в таблицу с 10 млн записей добавляем 1000 записей с "отложенным индексированием". В результате придется потом прочитать все 10млн записей, да еще и 10млн индексных чтений сделать.
Так что спорная штука.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562875
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladА что такое "входной поток" ? Где он начинается и где заканчивается ?эммм... ну вот когда движок начинает делать вот такое:
Код: sql
1.
insert into t select ... from s;

- то разве он не "чувствует", когда заканчиваются данные из источника ? Трейс же имеет ключик log_statement_finish - он же "видит" каким-то образом этот самый "финиш"...
hvladИ где найти ключи от всего только что вставленного "потока" ? Перечитывать 100500 записей ? Или копить всё в (резиновой) памяти по ходу вставок ?Даже если перечитывать (тест см ниже), будет ощутимый выигрыш. А если накапливать в памяти, так еще больше. Ибо чтобы исчерпать современные 16/32/64 Гб - это постараться надо.
К тому же, накапливая ключи в памяти, можно "на ходу" понять, хватит ли имеющейся памяти или нет и прекратить это накопление, выполенив в итоге простое перечитывание.
hvladЗа контроль уникальности я даже не заикаюсь.Я вёл речь только об insert'ах; delete & update тоже сюда подойдут. Merge - нет, тут безусловно надо контролировать сразу для каждой записи.
Если же прога написана так, что делает insert'ы недопустимых дубликатов - разраб ССЗБ, пусть переписывает на merge.
hvladПри чём тут вообще GTT\не GTT ???При том, что на них:
1) должен получиться наибольший выигрыш, т.к. их данные хранятся в /dev/shm (если настроить TempDirs как надо), там выключены careful writes;
2) в случае реализации такой фичи всякие ошибки (алгоритма этой реализации) будут менее болезненными. Ибо времянки.

Результат теста предсказуем и не интересен, но пусть будет как аргумент.

variant #1.
Создаем GTT, напихиваем в неё данные (5 млн строк), а затем перечитываем её всю для построения индексов:]
perfins_deferred_index_rebuild.sql
Код: 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.
set autoddl off;
commit;
recreate global temporary table gtt(id int, s01 varchar(36), s02 varchar(36), s03 varchar(36) )
on commit preserve rows;
commit;

set stat on;
set echo on;
set term ^;
execute block as
  declare n int = 5000000;
  declare i int = 0;
begin
  while (i<n) do
    insert into gtt(id, s01, s02, s03)
    values( :i,
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid())
          ) returning :i+1 into i;
end^
set term ;^
set stat off;
set echo on;
create unique index t_id on gtt(id);
create index t_s01 on gtt(s01);
create index t_s02 on gtt(s02);
create index t_s03 on gtt(s03);
set stat on;
commit;
exit;
Output:
133 + 33 = 266 sec
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
set term ^;
execute block as
  declare n int = 5000000;
  declare i int = 0;
begin
  while (i<n) do
    insert into gtt(id, s01, s02, s03)
    values( :i,
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid())
          ) returning :i+1 into i;
end^
Current memory = 20987952
Delta memory = 103768
Max memory = 23776040
 Elapsed time= 133.044 sec 
Cpu = 0.000 sec
Buffers = 2048
Reads = 5
Writes = 98136
Fetches = 15801650
set term ;^
set stat off;
set echo on;

create unique index t_id on gtt(id);
create index t_s01 on gtt(s01);
create index t_s02 on gtt(s02);
create index t_s03 on gtt(s03);
set stat on;
commit;
Current memory = 21203848
Delta memory = 168672
Max memory = 357819008
 Elapsed time= 32.622 sec 
Cpu = 0.000 sec
Buffers = 2048
Reads = 400336
Writes = 75565
Fetches = 40948184
exit;


variant #2 . Создаем GTT и к ней сразу - те же самые индексы. Заливаем данные, заставляя движок обновлять на каждой записи 4 индекса:
perfins_immediate_index_updating.sql
Код: 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.
set autoddl off;
commit;
recreate global temporary table gtt(id int, s01 varchar(36), s02 varchar(36), s03 varchar(36) )
on commit preserve rows;
commit;
create unique index t_id on gtt(id);
create index t_s01 on gtt(s01);
create index t_s02 on gtt(s02);
create index t_s03 on gtt(s03);
commit;

set stat on;
set echo on;
set term ^;
execute block as
  declare n int = 5000000;
  declare i int = 0;
begin
  while (i<n) do
    insert into gtt(id, s01, s02, s03)
    values( :i,
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid())
          ) returning :i+1 into i;
end^
set term ;^
commit;
exit;
Output:
472 sec
Код: 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.
33.
set term ^;
execute block as
  declare n int = 5000000;
  declare i int = 0;
begin
  while (i<n) do
    insert into gtt(id, s01, s02, s03)
    values( :i,
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid()),
            uuid_to_char(gen_uuid())
          ) returning :i+1 into i;
end^
Current memory = 21257024
Delta memory = 90056
Max memory = 24045376
 Elapsed time= 471.882 sec 
Cpu = 0.000 sec
Buffers = 2048
Reads = 14370102
Writes = 13999718
Fetches = 99245515
set term ;^
commit;
Current memory = 21201064
Delta memory = -55960
Max memory = 24045376
Elapsed time= 0.007 sec
Cpu = 0.000 sec
Buffers = 2048
Reads = 1
Writes = 1385
Fetches = 1
exit;
Разница = 472 / 266 = 1.77 раза.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562880
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvв таблицу с 10 млн записей добавляем 1000 записей с "отложенным индексированием". В результате придется потом прочитать все 10млн записей, да еще и 10млн индексных чтений сделать.
Так что спорная штука.в идеале было бы накапливать добавленные ключики в памяти. Сейчас век дешёвых гига/терабайтов, времена поменялись уже лет 10 как бэ... :-)
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562900
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

времена поменялись, сервера уже давно многопользовательские, а ты все оптимизируешь исключительно для себя любимого. Выкинет твой волшебный инсерт все конкурентные сортировки в своп и придут по твою душу злые клиенты и/или админы. Будешь им рассказывать про новые времена и свой подход к дешевым гигабайтам.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562915
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrВыкинет твой волшебный инсерт все конкурентные сортировки в своп и придут по твою душу злые клиенты и/или админы. Будешь им рассказывать про новые времена и свой подход к дешевым гигабайтам.Они и так придут, если я не выставлю адекватный TempCacheLimit, а не эти нищебродские 64 Мб :-)
И, кстати: а ведь можно ввести такой параметр, как максимальная квота использования TempSpace одним аттачем ? Тогда ко мне в комнату точно никто не придёт с б/битой. Кажеццо...
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562922
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидhvladЗа контроль уникальности я даже не заикаюсь.Я вёл речь только об insert'ахА их что - не надо контролировать ? А что делать параллельным коннектам, которые тоже что-то вставляют ?

ТаблоидЕсли же прога написана так, что делает insert'ы недопустимых дубликатов - разраб ССЗБ, пусть переписывает на merge.Так и сделаем - введём новый код ошибки isc_app_dev_is_a_fool и будем её возвращать. Всегда.

ТаблоидРезультат теста предсказуем и не интересен, но пусть будет как аргумент.С этим у тебя всегда проблемы. Твой тест не отражает реальности. Ибо при построении индекса применяется совсем не дакой алгоритм, как при добавлении ключей в индекс (пусти и пачки).


И вернёмся к начальному вопросу:
ТаблоидhvladА что такое "входной поток" ? Где он начинается и где заканчивается ?эммм... ну вот когда движок начинает делать вот такое:
Код: sql
1.
insert into t select ... from s;


- то разве он не "чувствует", когда заканчиваются данные из источника ?А теперь найди этот вот
Код: sql
1.
insert into t select ... from s;

в своём предсказуемом и не интересном (полностью согласен!) тесте
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562954
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,
отложенные индексы - бред. Я ещё понимаю если бы ты отложенных FK требовал. И чего ты так к этим GTT доматался? Если ты их используешь только для оптимизации выборок, то может лучше просить фич оптимизатора?
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38562992
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladТаблоидпропущено...Я вёл речь только об insert'ахА их что - не надо контролировать ? А что делать параллельным коннектам, которые тоже что-то вставляют ?куда, в GTT ? (разговор только о времянках!)

hvladТвой тест не отражает реальности. Ибо при построении индекса применяется совсем не дакой алгоритм, как при добавлении ключей в индекс (пусти и пачки).я знаю, что там всё по-другому; но сравнить, хотя бы с точностью два лаптя, - как еще ?

hvladА теперь найди этот вот
Код: sql
1.
insert into t select ... from s;

в своём предсказуемом и не интересном (полностью согласен!) тестекогда insert-команда содержит values(), то ясен пень, что тут нет окончания "входного потока". Этот пример был просто скопипастен с другого, с минимальными изменениями.
Речь идёт именно о случае, когда есть многострочный "источник" данных.
3.2 млн строк, deferred index rebuild: 96 + 21 = 117 сек
Код: 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.
$ /opt/fb30trnk/bin/isql localhost/3333:/var/db/fb30/perfins.fdb -i perfins_deferred_index_rebuild.sql
insert into gtt
select gen_id(g,1),uuid_to_char(gen_uuid()),uuid_to_char(gen_uuid()),uuid_to_char(gen_uuid())
from rdb$types,rdb$types,rdb$relations;
Current memory = 21691592
Delta memory = 673896
Max memory = 23662128
 Elapsed time= 96.494 sec 
Cpu = 0.000 sec
Buffers = 2048
Reads = 55
Writes = 68649
Fetches = 21873700

commit;
Elapsed time= 0.009 sec
. . .

create unique index t_id on gtt(id);
create index t_s02 on gtt(s02);
create index t_s03 on gtt(s03);

commit;
Current memory = 21911904
Delta memory = 168560
Max memory = 291420376
 Elapsed time= 20.928 sec 
Cpu = 0.000 sec
Buffers = 2048
Reads = 280546
Writes = 52023
Fetches = 28894253
== vs ==
3.2 млн строк, immediate index update: 285 sec
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
insert into gtt
select gen_id(g,1),uuid_to_char(gen_uuid()),uuid_to_char(gen_uuid()),uuid_to_char(gen_uuid())
from rdb$types,rdb$types,rdb$relations;
Current memory = 21971712
Delta memory = 85520
Max memory = 291420376
 Elapsed time= 285.282 sec 
Cpu = 0.000 sec
Buffers = 2048
Reads = 9456360
Writes = 9543423
Fetches = 77563527
commit;
Elapsed time= 0.007 sec
. . .


PS. у Cтаршего Брата много лет существует deferred constraints , проверяемые при commit'e транзакции (даже не по окончаниии стейтмента). Сильно подозреваю, что индексы, которыми обеспечиваются эти самые deferred-констрейнты (UK/FK), также обновляются в самом заду, не сразу. А также (как минимум с 11.1.0) - deferred index maintenance - судя по тексту, это как раз то самое , "с ключиками в памяти".
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563002
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисотложенные индексы - бред.Обоснуй.
Симонов ДенисЯ ещё понимаю если бы ты отложенных FK требовал. И чего ты так к этим GTT доматался? Если ты их используешь только для оптимизации выборок, то может лучше просить фич оптимизатора?Использую, и не я один. Запрос такой фичи оптимизатора (материализацию промежуточных результатов) делать не нужно, она есть вроде бы. По кр. мере, я точно знаю, что ДЕ в трёшке что-то делает (или почти сделал) в этом направлении.

Но GTT'шки юзаются не только для ускорения джойнов. Например, загрузить из файла прайс-лист поставщика с предпросмотром его перед окончательным импортом. Там может быть 1...2 млн строк (речь о запчастях), юзера могут выполнять в нём поиск, всякие модификации цен, скидочных категорий и проч. Джойнов тут нет вообще. Надо просто загрузить его побыстрее и проиндексировать.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563034
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидPS. у Cтаршего Брата много лет существует deferred constraints , проверяемые при commit'e транзакции (даже не по окончаниии стейтмента). Сильно подозреваю, что индексы, которыми обеспечиваются эти самые deferred-констрейнты (UK/FK), также обновляются в самом заду, не сразу.

с чего ты взял, что deferred constraints будут работать быстрее чем построчные? Да и применяются они не для скорости, а именно чтобы отложить проверку, что как бы следует из названия.

Что касается ускорения загрузки (insert), то тут лучше бы ты просил bulk insert. По-моему даже в трекере где-то есть insert со множественным values.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563041
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисЧто касается ускорения загрузки (insert), то тут лучше бы ты просил
bulk insert. По-моему даже в трекере где-то есть insert со множественным values.
Array DML было бы эффективнее.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563049
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид(разговор только о времянках!)Это ты так думаешь

Таблоидя знаю, что там всё по-другому; но сравнить, хотя бы с точностью два лаптя, - как еще ?Ты делаешь утверждения - ты их обосновываешь. Пока что твои обоснования не выдерживают критики

Таблоиду Cтаршего Брата много лет существуетЯ знаю. Но у него много чего ещё существует.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563052
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисс чего ты взял, что deferred constraints будут работать быстрее чем построчные? Да и применяются они не для скорости, а именно чтобы отложить проверку, что как бы следует из названия.я знаю, что они для откладывания проверки. Скорость не сравнивал, в лом. А второй ссылки, про deferred index maintenance, разве не достаточно, чтобы просто обратить внимание на это ?
Симонов ДенисЧто касается ускорения загрузки (insert), то тут лучше бы ты просил bulk insert. По-моему даже в трекере где-то есть insert со множественным values.а что ты вкладываешь в эту фразу, bulk insert ? что при этом должно/ не должно происходить ?
ЗЫ. тикета не вижу; есть только фикс регресса, недавний.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563053
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

ну или это

Таблоид,

подозреваю что вот это deferred constraints требует блокировки. Да и часто ли ты их применял в ORA. Лично я вижу их пользу только для отложенных FK, да и то только для случая когда в таблицу запихивается древовидная структура и не возможно вставить какую либо запись до вставки её родителя. В остальных случаях порядок вставки всегда можно определить.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563061
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladТы делаешь утверждения - ты их обосновываешь. Пока что твои обоснования не выдерживают критики.ну, а как еще сравнивать-то ? при отсутствии чего-то типа "обнови индекс только по добавленным строкам" ? :-)
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563063
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

CORE-1978 как по мне так это часть CORE-3880
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563072
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис CORE-1978 как по мне так это часть CORE-3880 Это не bulk insert, а именно "конструктор" с заранее известными числами внутри values(). Просто что бы не ходить на поклон к rdb$database. Индексы по-прежнему будут обновляться для каждой добавляемой записи.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563081
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

я тут только об уменьшении кол-ва round-trip на массовых вставках и это полезно не только для GTT. Про индексы я тут не говорил. Что касается именно отложенных констрейнов, то тебе уже говорили, что если и делать, то для всех таблиц, а не только для GTT. А это куда сложнее
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563085
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидhvladТы делаешь утверждения - ты их обосновываешь. Пока что твои обоснования не выдерживают критики.ну, а как еще сравнивать-то ? Проблемы индейцев ... (ц)
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563097
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladТаблоидпропущено...ну, а как еще сравнивать-то ? Проблемы индейцев ... (ц)дежурно-казённая отговорка :-)
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563176
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидИспользую, и не я один. Запрос такой фичи оптимизатора (материализацию промежуточных результатов) делать не нужно, она есть вроде бы. По кр. мере, я точно знаю, что ДЕ в трёшке что-то делает (или почти сделал) в этом направлении.

я тоже в некоторых местах использую. Но это от бедности. Кстати разве оконные функции не покрывают 50% таких задач? Материализацию промежуточных результатов покроет ещё 15%. Правда есть у меня одна задачка в которой пока заменить GTT никак не удаётся.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563196
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денися тоже в некоторых местах использую. Но это от бедности. Кстати разве оконные функции не покрывают 50% таких задач?ты про sum()over() и сравнение с ним значений в соседних столбах для последующего фильтра или про что ?

Симонов ДенисМатериализацию промежуточных результатов покроет ещё 15%. Правда есть у меня одна задачка в которой пока заменить GTT никак не удаётся.я видел её, но не вчитывался, по правде сказать. Надо будет глянуть как-нить.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563212
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидты про sum()over() и сравнение с ним значений в соседних столбах для последующего фильтра или про что ?

да и не только. Жаль пока нету спецификации кадрирования.

ТаблоидСимонов ДенисМатериализацию промежуточных результатов покроет ещё 15%. Правда есть у меня одна задачка в которой пока заменить GTT никак не удаётся.я видел её, но не вчитывался, по правде сказать. Надо будет глянуть как-нить.
на самом деле там упрощённая формулировка, на самом деле там помимо коэффициента надо ещё вывести полную родословную с пометкой всех инбредных лошадей и раскрасить их разными цветами. Я пробовал на досуге решить это с помощью оконных функций, но до конца так и не добил. Да и работало оно медленней, чем с GTT.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563522
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dimitrbazilio77,

во-первых, только при установленных в -1 параметрах MaxUnflushed* в конфиге. Во-вторых, все-таки проигрывает, пусть и немного.
Ви таки будете смеяться.
Оказалось что на том диске где я проводил тесты оказалась включена компрессия NTFS.
Выключил компрессию в каталоге где лежала БД и получил результат равный рамдиску или даже
быстрее 2:17 vs 2.21 на рамдиске.
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563568
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazilio77,

а индексация ? :-)
...
Рейтинг: 0 / 0
Еще раз о ramdisk
    #38563585
bazilio77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ariochbazilio77,

а индексация ? :-)
Индексация чего?
...
Рейтинг: 0 / 0
47 сообщений из 47, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Еще раз о ramdisk
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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