powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
7 сообщений из 7, страница 1 из 1
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39037898
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all.

Понадобилось как-то затащить в таблицу оч-чень много строк из базы-источника. DDL таблиц полностью совпадает, перенос идёт с помощью IB DataPump.
Ясен пень, что если убрать индексы с таблицы-приёмника, то скорость увеличится. Но захотелось также выкинуть (временно) все check'и на ней - "а вдруг взлетит еще быстрее ?".

Результат для 2.5 слегка удивил.
Если not-null задано вот так:
Код: sql
1.
recreate table tgt1(id int not null); -- field-defined not-null constraint

или вот так:
Код: sql
1.
2.
create domain dm_id_check_nn int check(value is not null);
recreate table tgt4(id dm_id_check_nn); -- nullable domain + EXPLICIT constraint on domain

или еще вот так:
Код: sql
1.
2.
3.
create domain dm_id_not_null int not null;
recreate table tgt5(id dm_id_not_null);
insert into tgt5 select * from src; -- NOT-null domain constraint

-- то скорость инсертов от наличия/отсутствия этих констрейнтов практически НЕ меняется.

Если же not-null обеспечивается в явном виде:
Код: sql
1.
2.
recreate table tgt2(id int, constraint tgt2_chk_id_nn check(id is not null));
insert into tgt2 select * from src; -- EXPLICIT not-null constraint on field

или вообще по-дэбильному:
Код: sql
1.
2.
recreate table tgt3(id int); create trigger tgt3_biu for tgt3 active before insert or update as begin if (new.id is null) then exception exc_id_nn; end
insert into tgt3 select * from src; -- trigger checking

-- то скорость инсертов от удаления этих перлов растёт ( в 2.5 ) примерно в 3 раза.

Почему так сильно проигрывают предпоследний и последний варианты ? (вариант через триггер хотя и выглядит "не комильфо", однако все check'и ведь тоже внутрях реализованы как триггера! Поэтому столь большая разница как-то настораживает).

#######################

Результат для 3.0 также породил душевные терзания.
В нём явный проигрыш в скорости инсертов наблюдается там же, где и для 2.5. Однако статистика вставок проигрывает во всех остальных случаях проигрывает примерно в 1.5 раза. ДЕ мне как-то говорил, что 3.0 будет выигрывать у 2.5 только при многопользовательской нагрузке, а в моно-коннекте выигрыш совсем не гарантирован. Однако дифферент 1.5 раза - как-то уж очень сильно... :( Получается, миграцию действительно больших данных вообще лучше в 2.5 делать, а затем b/r ?

Вот тест:
Код: 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.
-- init DDL:
recreate table src(id int);
commit;
set term ^;
execute block as
  declare n int = 2000000;
begin
  while (n>0) do insert into src(id) values(:n) returning :n-1 into n;
end
^
set term ;^
commit;

-- test:

set bail on;
recreate table tgt0(id int);
recreate table tgt1(id int not null);
recreate table tgt2(id int, constraint tgt2_chk_id_nn check(id is not null));
recreate table tgt3(id int);
recreate table tgt4(id int);
recreate table tgt5(id int);
commit;

set term ^;
execute block as
begin
  begin
    execute statement 'drop domain dm_id_check_nn';
    when any do begin end
  end
  begin
    execute statement 'drop domain dm_id_not_null';
    when any do begin end
  end
  begin
    execute statement 'drop exception exc_id_nn';
    when any do begin end
  end
end
^
set term ;^
commit;
create domain dm_id_check_nn int check(value is not null);
create domain dm_id_not_null int not null;
commit;

recreate table tgt4(id dm_id_check_nn);
recreate table tgt5(id dm_id_not_null);

create exception exc_id_nn 'id is null';
commit;

set term ^;
create trigger tgt3_biu for tgt3 active before insert or update as
begin
  if (new.id is null) then exception exc_id_nn;
end
^
set term ;^
commit;

set stat on;
set count on;
set echo on;

insert into tgt0 select * from src; -- no conctraints
insert into tgt1 select * from src; -- field-defined constraint
insert into tgt2 select * from src; -- EXPLICIT not-null constraint on field
insert into tgt3 select * from src; -- trigger checking
insert into tgt4 select * from src; -- domain, EXPLICIT constraint
insert into tgt5 select * from src; -- domain-defined not-null constraint
set echo off;
set stat off;
commit;

А вот сводный результат по пяти запускам на каждом ФБ (приведены данные, начиная со второго прогона в каждом случае, дабы убрать влияние затрат на рост файла БД):

0.
Код: plaintext
1.
recreate table tgt0(id int);
insert into tgt0 select * from src; -- no conctraints
run-1run-2run-3run-4run-5elapsed_ms, FB 3.0 SC51075083508350835121elapsed_ms, FB 2.5 SC32883297330332843286ratio: 3.0 / 2.5:1,551,541,541,551,56

1.
Код: plaintext
1.
recreate table tgt1(id int not null);
insert into tgt1 select * from src; -- field-defined not-null constraint
run-1run-2run-3run-4run-5elapsed_ms, FB 3.0 SC53105303528653025307elapsed_ms, FB 2.5 SC35493546353135133500ratio: 3.0 / 2.5:1,501,501,501,511,52

2.
Код: plaintext
1.
recreate table tgt2(id int, constraint tgt2_chk_id_nn check(id is not null));
insert into tgt2 select * from src; -- EXPLICIT not-null constraint on field
run-1run-2run-3run-4run-5elapsed_ms, FB 3.0 SC74807474748574818199elapsed_ms, FB 2.5 SC1010610125100911009510098ratio: 3.0 / 2.5:0,740,740,740,740,81

3.
Код: plaintext
1.
2.
recreate table tgt3(id int); 
create trigger tgt3_biu for tgt3 ... as begin if (new.id is null) then exception exc_id_nn; end
insert into tgt3 select * from src; -- trigger checking
run-1run-2run-3run-4run-5elapsed_ms, FB 3.0 SC89358907958989098981elapsed_ms, FB 2.5 SC1194812103114961244911990ratio: 3.0 / 2.5:0,750,740,830,720,75

4.
Код: plaintext
1.
2.
3.
create domain dm_id_check_nn int check(value is not null);
recreate table tgt4(id dm_id_check_nn);
insert into tgt4 select * from src; -- domain, EXPLICIT constraint
run-1run-2run-3run-4run-5elapsed_ms, FB 3.0 SC53625317531453105301elapsed_ms, FB 2.5 SC35383518351635373523ratio: 3.0 / 2.5:1,521,511,511,501,50

5.
Код: plaintext
1.
2.
create domain dm_id_not_null int not null;
recreate table tgt5(id dm_id_not_null);
insert into tgt5 select * from src; -- domain-defined not-null constraint
run-1run-2run-3run-4run-5elapsed_ms, FB 3.0 SC55995329532853255323elapsed_ms, FB 2.5 SC39983549350535193497ratio: 3.0 / 2.5:1,401,501,521,511,52

PS.
Версии ФБ:
LI-V2.5.5.26910
LI-V3.0.0.32008

База в обоих случаях: page_size = 4K, fw = OFF.
Кол-во буферов в обоих инстансах ФБ: 512, арх-ра: SuperClassic.
...
Рейтинг: 0 / 0
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39037912
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидПочему так сильно проигрывают предпоследний и последний варианты ?
потому что там есть вызов триггера на каждую запись
...
Рейтинг: 0 / 0
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39037996
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

хорошо, а "кто" тогда выполняет проверки в остальных трёх вариантах:

Код: sql
1.
2.
3.
4.
5.
6.
7.
recreate table tgt1(id int not null);
--
create domain dm_id_check_nn int check(value is not null);
recreate table tgt4(id dm_id_check_nn);
---
create domain dm_id_not_null int not null;
recreate table tgt5(id dm_id_not_null);

- ?
...
Рейтинг: 0 / 0
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39038064
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид"кто" тогда выполняет проверки в остальных трёх вариантах
сам движок
...
Рейтинг: 0 / 0
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39038091
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

в твоём тесте получается, что в трёшке триггеры работают быстрее, а движок медленнее. Странно это...

И ещё у тебя тест не совсем чистый. Где гарантия что медленней именно insert, а не select * from src
Сколько там хоть записей то и как они распределены?
...
Рейтинг: 0 / 0
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39038149
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисв трёшке триггеры работают быстрее, а движок медленнее. Странно это...
странно то, что триггеры быстрее :-)
...
Рейтинг: 0 / 0
bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
    #39038352
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисв твоём тесте получается, что в трёшке триггеры работают быстрее, а движок медленнее. Странно это...ну, вот так вот... прогони у себя, получишь, скорее всего тоже самое.

Симонов ДенисИ ещё у тебя тест не совсем чистый. Где гарантия что медленней именно insert, а не select * from src
Сколько там хоть записей то и как они распределены?затраты на select * from src - это по-любасу постоянная величина. И в стартовом посте всё видно, под спойлером: таблица содержит только числовое поле ID, от 1 до 2'000'000. Индексов нигде нету.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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