powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / where not exists сильно тормозит
48 сообщений из 48, показаны все 2 страниц
where not exists сильно тормозит
    #39934510
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую.

Есть много запросов такого типа:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
delete from utable
where not exists (
  select 1 
  from table1 t1
  join table2 t2 join t1
  join table3 t3 join t2

  where utable.fld1 = t1.fld1
  and utable.fld2 = t2.fld2
  and utable.fld3 = t3.fld3
)



Если delete заменить на select *, то сути это не изменит. Так вот, запросы эти дико тормозят (выполняются более чем суток, потом я их прибиваю). По каждому полю каждой таблицы, которые участвуют в where вложенного запроса есть fk-индекс + у utable стоит unique на все поля. У полей, которые участвуют в join-е, есть pk- и fk- индексы.
Примерное количество записей в таблицах: utable ~25000, в наибольшей table* ~5 млн. Все поля в запросе - integer

Статистика индексов посчитана. В какую сторону копать? Если надо, выложу реальные ddl и запросы.

PS: Система работает с разными СУБД. На тех же данных (но без fk-индексов) последний постгрес отрабатывает менее чем за 10 секунд на не разогретой базе. Надо что-то придумать, чтобы чтобы FB не сильно от него отставал.

PPS: FB 2.5.8.27089 x64, 10я винда

PPPS: если переписать запрос на right join с where is null, то ситуация не улучшается.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934517
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

я так понимаю запрос совсем не реальный, ибо условий соединения в join нет.

NOT EXISTS плохо оптимизируется, HASH OUTER JOIN у нас пока нет
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934533
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

5 млн - это не сутки, в любом случае.

иногда делаю

Код: sql
1.
2.
3.
4.
5.
6.
for select t1.ID 
     from t1
             join t2 on t2.ID_T1 = t1.ID
    where t2.ID is null
    into :ID1
    do delete from t1 where ID = :ID1;



PS можно через курсор WHERE OF
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934540
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastor
иногда делаю
LEFT
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934560
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно пример хоть маленько приближенный к реальным метаданным?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934592
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery
pastor
иногда делаю
LEFT


mea culpa, mea maxima culpa

конечно же LEFT
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934669
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ivan_Pisarevsky, Поубирал из ddl-ля поля, которые не участвуют в запросе, но всё равно много получается. Вот такое удаление выполняется почти сутки (скоро буду прибивать):

Код: sql
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.
create table ws_database(
	id         integer not null,

	constraint pk_ws_database_id primary key (id)
);

create table files(
	id            integer not null,
	db_id         integer,

	constraint pk_files_id    primary key (id),
	constraint fk_files_db_id foreign key (db_id) references ws_database(id)  on delete cascade
);


create table history_user (
	id_user integer not null,
	name    varchar(240),

	constraint pk_history_user     primary key (id_user),
	constraint u_history_user_name unique      (name)
);

create table history_comp (
	id_comp integer not null,
	name    varchar(240),

	constraint pk_history_comp     primary key (id_comp),
	constraint u_history_comp_name unique      (name)
);

create table table_names(
	id   integer not null,
	name varchar(128) not null,

	constraint pk_table_names_id  primary key (id),
	constraint u_table_names_name unique      (name)
);


create table history_table (
	id_table integer not null,
	id_file  integer not null,
	id_name  integer not null,

	constraint pk_history_table_id_table  primary key (id_table),
	constraint fk_history_table_id_file   foreign key (id_file) references files(id) on delete cascade,
	constraint fk_history_table_id_name   foreign key (id_name) references table_names(id),
	constraint u_history_table            unique      (id_file,id_name)
);

create table history_row (
	id_row   integer not null,
	id_table integer not null,
	keystr   varchar(2048),

	constraint pk_history_row_id_row   primary key (id_row),
	constraint fk_history_row_id_table foreign key (id_table) references history_table(id_table) on delete cascade
);

create table history (
	id_rec     integer default -1 not null,
	id_row     integer not null,
	id_module  integer not null,
	id_user    integer not null,
	id_comp    integer not null,
	id_array   integer not null,
	id_col     integer not null,
	modifytype integer not null,
	datetime   timestamp not null,

	constraint pk_history           primary key (id_rec),
	constraint fk_history_id_row    foreign key (id_row)    references history_row   (id_row) on delete cascade,
	constraint fk_history_id_user   foreign key (id_user)   references history_user  (id_user),
	constraint fk_history_id_comp   foreign key (id_comp)   references history_comp  (id_comp)
);

create table fast_history (
	db_id    integer not null,
	tname_id integer not null,
	id_user  integer not null,
	id_comp  integer not null,

	constraint fk_fast_history_dbid foreign key (db_id)   references ws_database  (id) on delete cascade,

	constraint fk_fast_history_tn   foreign key (tname_id) references table_names  (id),
	constraint fk_fast_history_user foreign key (id_user)  references history_user (id_user),
	constraint fk_fast_history_comp foreign key (id_comp)  references history_comp (id_comp),
	constraint u_fast_history       unique      (db_id,tname_id,id_user,id_comp)
);

commit;

delete from fast_history 
where not exists( 
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = fast_history.db_id 
	and t.id_name = fast_history.tname_id 
	and h.id_user = fast_history.id_user 
	and h.id_comp = fast_history.id_comp 
);



Количество записей history - 5 млн, fast_history - 25000, history_row - 1.5 млн, history_table - 400 тыс, files - 60тыс. Остальные - несколько десятков
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934675
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

план запроса какой?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934698
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdv,

PLAN JOIN (JOIN (H INDEX (FK_HISTORY_IDCOMP, FK_HISTORY_IDUSER), JOIN (T INDEX (FK_HISTORYTABLE_IDNAME), F INDEX (PK_FILES_ID))), R INDEX (PK_HISTORYROW_IDROW))
PLAN (FAST_HISTORY NATURAL)
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934711
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
kdv,

PLAN JOIN (JOIN (H INDEX (FK_HISTORY_IDCOMP, FK_HISTORY_IDUSER), JOIN (T INDEX (FK_HISTORYTABLE_IDNAME), F INDEX (PK_FILES_ID))), R INDEX (PK_HISTORYROW_IDROW))
PLAN (FAST_HISTORY NATURAL)


А сколько различных значений
у ID_USER и ID_COMP
????
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934712
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDenPLAN (FAST_HISTORY NATURAL)
так я и знал! Ну, значит, вложенный запрос выполняется 25 тысяч раз.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934715
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv
ArtDenPLAN (FAST_HISTORY NATURAL)

так я и знал! Ну, значит, вложенный запрос выполняется 25 тысяч раз.

А что тут можно было ожидать чего-то другого
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934717
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m,

900 и 1200

Получается, я ошибся. В остальных справочных таблицах не несколько десятков, в несколько сотен записей.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934720
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем, нужны рекомендации. При необходимости могу немного поменять структуру базы, если другими способами невозможно что либо сделать.

PS: SQL-запрос должен быть без расширений FB, чтобы он отрабатывал на других СУБД
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934721
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

тут ничего удивительного. Как я уже говорил HASH OUTER JOIN ФБ пока не умеет. Ты ещё и дополнительный геморрой себе отрастил тем, что не сделал искусственный ПК в fast_history. Если бы он был можно было бы повоевать вот так


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
delete from fast_history fh1
where not exists( 
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
        join fast_history fh2 on
	    f.db_id = fh2.db_id and 
            t.id_name = fh2.tname_id and
	    h.id_user = fh2.id_user and
	    h.id_comp = fh2.id_comp 
       where fh2.id = fh1.id
);



не факт что было бы быстрее, но мало ли.

Вот это

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	select count(*) 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
        join fast_history fh2 on
	    f.db_id = fh2.db_id and 
            t.id_name = fh2.tname_id and
	    h.id_user = fh2.id_user and
	    h.id_comp = fh2.id_comp 



сколько выполняется?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934739
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
сколько выполняется?

Ждал почти 20 минут. Не дождался, прибил.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934749
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
m7m,

900 и 1200


и получается около 5000 дубликатов в таблице history на каждое значение
и вот этот кусок
H INDEX (FK_HISTORY_IDCOMP, FK_HISTORY_IDUSER)
совсем не вселяет оптимизма

Возможно чуток может помочь избавление в плане от одного из этих индексов
Возможно немного больше поможет составной индекс ID_COMP,ID_USER
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934756
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
Вот это

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	select count(*) 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
        join fast_history fh2 on
	    f.db_id = fh2.db_id and 
            t.id_name = fh2.tname_id and
	    h.id_user = fh2.id_user and
	    h.id_comp = fh2.id_comp 




сколько выполняется?

Денис возможно все-же время выполнения этого запроса
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = :Fast_history_db_id 
	and t.id_name = :Fast_history_tname_id 
	and h.id_user = :Fast_history_id_user 
	and h.id_comp = :Fast_history_id_comp 


более интересно
тем более что именно его и надо оптимизировать
Хотя что тут интересного по сообщениям и так ясно что он тормозит
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934760
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m,

1. Запустил
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
delete from fast_history 
where not exists( 
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = fast_history.db_id 
	and t.id_name = fast_history.tname_id 
	and h.id_user+0 = fast_history.id_user 
	and h.id_comp+0 = fast_history.id_comp 
)


Жду. +0 в правильном месте?
План получился
PLAN JOIN (JOIN (JOIN (T INDEX (FK_HISTORYTABLE_IDNAME), F INDEX (PK_FILES_ID)), R INDEX (FK_HISTORYROW_IDTABLE)), H INDEX (FK_HISTORY_IDROW))
PLAN (FAST_HISTORY NATURAL)

2. Составными индексами уже наигрался. Они дали выигрыш в других запросах с меньшим количеством join. Могу ещё раз попробовать.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934768
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m

Денис возможно все-же время выполнения этого запроса
более интересно
тем более что именно его и надо оптимизировать
Хотя что тут интересного по сообщениям и так ясно что он тормозит

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = (select first 1 DB_ID from FAST_HISTORY)
	and t.id_name = (select first 1 TNAME_ID from FAST_HISTORY)
	and h.id_user = (select first 1 ID_USER from FAST_HISTORY)
	and h.id_comp = (select first 1 ID_COMP from FAST_HISTORY)



0.03 sec
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934780
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
m7m

Денис возможно все-же время выполнения этого запроса
более интересно
тем более что именно его и надо оптимизировать
Хотя что тут интересного по сообщениям и так ясно что он тормозит

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = (select first 1 DB_ID from FAST_HISTORY)
	and t.id_name = (select first 1 TNAME_ID from FAST_HISTORY)
	and h.id_user = (select first 1 ID_USER from FAST_HISTORY)
	and h.id_comp = (select first 1 ID_COMP from FAST_HISTORY)




0.03 sec


План какой?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934836
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

чую у вас в мусор в fast_history накопился при неудачных удалениях


Код: sql
1.
select count(*) from fast_history




А потом оптимизировать надо, а не сам delete

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select count(*) from fast_history 
where not exists( 
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = fast_history.db_id 
	and t.id_name = fast_history.tname_id 
	and h.id_user = fast_history.id_user 
	and h.id_comp = fast_history.id_comp 
)
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934868
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
0.03 sec


25000 * 0.03 /60=12.5 минут
ну пусть 15 минут
что-то у меня в голове не складывается
может быть действительно
Симонов Денис
чую у вас в мусор в fast_history накопился при неудачных удалениях
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934884
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

gstat -r -t fast_history

?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934896
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот
Код: 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.
91.
Database header page information:
	Flags			0
	Checksum		12345
	Generation		130468
	Page size		16384
	ODS version		11.2
	Oldest transaction	130452
	Oldest active		130453
	Oldest snapshot		130448
	Next transaction	130458
	Bumped transaction	1
	Sequence number		0
	Next attachment ID	111
	Implementation ID	26
	Shadow count		0
	Page buffers		0
	Next header page	0
	Database dialect	3
	Creation date		Feb 29, 2020 17:18:29
	Attributes		

    Variable header data:
	*END*


Database file sequence:
File E:\PrimeDbFirebirdDatabase\PRIME1.FBDB is the only file

Analyzing database pages ...
FAST_HISTORY (220)
    Primary pointer page: 613, Index root page: 614
    Average record length: 21.00, total records: 24945
    Average version length: 0.00, total versions: 0, max versions: 0
    Data pages: 95, data page slots: 95, average fill: 61%
    Fill distribution:
	 0 - 19% = 0
	20 - 39% = 1
	40 - 59% = 0
	60 - 79% = 94
	80 - 99% = 0

    Index FK_FASTHISTORY_DBID (0)
	Depth: 2, leaf buckets: 7, nodes: 24945
	Average data length: 0.00, total dup: 24929, max dup: 20405
	Fill distribution:
	     0 - 19% = 1
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 0
	    80 - 99% = 6

    Index FK_FASTHISTORY_IDCOMP (3)
	Depth: 2, leaf buckets: 10, nodes: 24945
	Average data length: 0.09, total dup: 23730, max dup: 295
	Fill distribution:
	     0 - 19% = 1
	    20 - 39% = 0
	    40 - 59% = 4
	    60 - 79% = 3
	    80 - 99% = 2

    Index FK_FASTHISTORY_IDUSER (2)
	Depth: 2, leaf buckets: 9, nodes: 24945
	Average data length: 0.07, total dup: 24018, max dup: 1375
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 2
	    60 - 79% = 5
	    80 - 99% = 2

    Index FK_FASTHISTORY_TNAMEID (1)
	Depth: 2, leaf buckets: 8, nodes: 24945
	Average data length: 0.10, total dup: 23224, max dup: 1509
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 5
	    80 - 99% = 3

    Index U_FASTHISTORY_DBID_IDCOMP_I (4)
	Depth: 2, leaf buckets: 17, nodes: 24945
	Average data length: 2.37, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 8
	    60 - 79% = 8
	    80 - 99% = 1



Данные свежезагруженные. Реально в таблице FAST_HISTORY нету данных для удаления. Т.е. запрос должен отработать вхолостую.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934918
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m
0.03 sec
План какой?

PLAN (FAST_HISTORY NATURAL)
PLAN (FAST_HISTORY NATURAL)
PLAN (FAST_HISTORY NATURAL)
PLAN (FAST_HISTORY NATURAL)
PLAN JOIN (H INDEX (FK_HISTORY_IDCOMP, FK_HISTORY_IDUSER), R INDEX (PK_HISTORYROW_IDROW), T INDEX (PK_HISTORYTABLE_IDTABLE), F INDEX (PK_FILES_ID))
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39934919
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
m7m
0.03 sec
План какой?

PLAN (FAST_HISTORY NATURAL)
PLAN (FAST_HISTORY NATURAL)
PLAN (FAST_HISTORY NATURAL)
PLAN (FAST_HISTORY NATURAL)
PLAN JOIN (H INDEX (FK_HISTORY_IDCOMP, FK_HISTORY_IDUSER), R INDEX (PK_HISTORYROW_IDROW), T INDEX (PK_HISTORYTABLE_IDTABLE), F INDEX (PK_FILES_ID))

Точно такой -же как и при удалении
мои фантазии иссякли :(
Надо ждать более знающих
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935023
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подропал всё лишнее и обфусциоровал словари. Вот реальные данные для тестирования:

https://drive.google.com/file/d/1FIEUiyUU9EuF77nDRzg5wtgeLxTm0tFb/view?usp=sharing

Пароль на архив - 123

Буду рад любым рекомендациям

Напоминаю, что дико тормозит запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
delete from fast_history 
where not exists( 
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = fast_history.db_id 
	and t.id_name = fast_history.tname_id 
	and h.id_user = fast_history.id_user 
	and h.id_comp = fast_history.id_comp 
);
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935028
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

курил вчера вечером на тестовых данных сгенерированных IBExpert. Пока успехов нет ((
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935048
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
execute block позволяет до 16 сек сократить время, но насколько я понимаю требуется совместимость запроса с другими СУБД...
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935061
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну или на стандартный MERGE переписать, там тоже 16 сек выходит. Но для этого надо на ФБ3 перейти. И не уверен, что PG поддерживает MERGE ... DELETE.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935066
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пусть побудут эти варианты для разнообразия. Они под 3-ку заточены, но первый можно адаптировать под 2.5. Оба дают 16 сек.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
execute block as
begin
  for select distinct h.id_user, h.id_comp, t.id_name, f.db_id
    from history h 
    join history_row r on h.id_row = r.id_row 
    join history_table t on t.id_table = r.id_table 
    join files f on f.id = t.id_file 
  as cursor c
  do
    delete from fast_history
    where db_id = c.db_id
      and tname_id = c.id_name
      and id_user = c.id_user
      and id_comp = c.id_comp;
end^



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
merge into fast_history h
using (
  select distinct h.id_user, h.id_comp, t.id_name, f.db_id
  from history h 
  join history_row r on h.id_row = r.id_row 
  join history_table t on t.id_table = r.id_table 
  join files f on f.id = t.id_file ) q
on q.db_id = h.db_id 
  and q.id_name = h.tname_id 
  and q.id_user = h.id_user 
  and q.id_comp = h.id_comp 
when matched then delete;
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935067
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

а как написать MERGE для удаления не существующих? Он вроде DELETE делает только для WHEN MATCHED
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935072
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, я для удаления существующих написал. Невнимателен, пардон.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935074
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

По моему это не совсем то, у него всё-таки NOT EXISTS
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935075
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
даже "совсем не то", я бы сказал :-)
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935141
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

У меня получилось убыстрить через промежуточную таблицу
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
create table T (
    DB_ID    integer not null,
    ID_NAME  integer not null,
    ID_USER  integer not null,
    ID_COMP  integer not null
);

create index IDX_T on T ( DB_ID, ID_NAME, ID_USER, ID_COMP );


Заполнение таблицы ~13 сек
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
insert into T
select distinct
       f.DB_ID,
       t.ID_NAME,
       h.ID_USER,
       h.ID_COMP
  from HISTORY h
  join HISTORY_ROW r   on ( h.ID_ROW   = r.ID_ROW   )
  join HISTORY_TABLE t on ( t.ID_TABLE = r.ID_TABLE )
  join FILES f         on ( f.ID       = t.ID_FILE  )
;
commit;



Запрос практически мгновенно
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select count(*)
  from FAST_HISTORY fh
 where not exists ( select *
                      from T
                     where t.DB_ID   = fh.DB_ID    and
                           t.ID_NAME = fh.TNAME_ID and
                           t.ID_USER = fh.ID_USER  and
                           t.ID_COMP = fh.ID_COMP )


Сгенеренные данные:
Код: powershell
1.
2.
3.
4.
5.
FAST_HISTORY      25000
FILES             60000
HISTORY         5000000
HISTORY_ROW     1500000
HISTORY_TABLE    400000


Остальные таблицы по 100 записей.

P.S. Надеюсь, ничего не перепутал.

С уважением, Polesov.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935155
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen,

кстати fast_history это ведь хранимый агрегат?
Если да, то может и правда не надо заморачиваться с удалением не существующих, а просто удалять всё и заполнять заново.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935158
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UPD

На предоставленных данных:

Вставка в промежуточную таблицу ~16 сек

Запрос с select ~94 мсек

Запрос с delete ~109 мсек
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935204
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
кстати fast_history это ведь хранимый агрегат?
Если да, то может и правда не надо заморачиваться с удалением не существующих, а просто удалять всё и заполнять заново.


Так раньше и происходило. Раз в сутки около часа ночи запускался скрипт, который делал полный delete, а потом её заполнял, запросом один-в-один похожим на запрос от Polesov:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
delete from fast_history;

insert into fast_history(db_id, tname_id, id_user, id_comp) 
select distinct f.db_id, t.id_name, h.id_user, h.id_comp 
from history h 
join history_row r on h.id_row = r.id_row 
join history_table t on t.id_table = r.id_table 
join files f on f.id = t.id_file 
where f.is_main != 0;

commit;



В какой-то момент мне показалось, что это не правильно - всё грохать и заполнять данные. И я переписал всё это на такой вариант:

Код: sql
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.
delete from fast_history 
where not exists( 
	select 1 
	from history h 
	join history_row r on h.id_row = r.id_row 
	join history_table t on t.id_table = r.id_table 
	join files f on f.id = t.id_file 
	where f.db_id = fast_history.db_id 
	and t.id_name = fast_history.tname_id 
	and h.id_user = fast_history.id_user 
	and h.id_comp = fast_history.id_comp 
);

insert into fast_history(db_id, tname_id, id_user, id_comp) 
select distinct f.db_id, t.id_name, h.id_user, h.id_comp 
from history h 
join history_row r on h.id_row = r.id_row 
join history_table t on t.id_table = r.id_table 
join files f on f.id = t.id_file 
where f.is_main != 0 
and not exists ( 
	select 1 
	from fast_history fh 
	where f.db_id = fh.db_id 
	and t.id_name = fh.tname_id 
	and h.id_user = fh.id_user 
	and h.id_comp  = fh.id_comp 
);
commit;


Delete удаляет из fast_history только записи, который там быть не должно, а Insert довставляет те, которые могли случайно не вставиться в течение суток. На моё удивление в первую же ночь лог показал, что запрос на удаление повис. Слава богу пользователям это не ушло.
Причём к insert-у нету претензий. Он отрабатывает за минуту на неразогретой базе и 20 секунд на разогретой, что меня полностью устраивает.

Вот сейчас думаю, что же делать со всеми этими запросами. А fast-таблиц у меня дофига...
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935212
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
Вот сейчас думаю, что же делать со всеми этими запросами. А fast-таблиц у меня дофига...
В чём проблема вернуться к delete+insert ?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935246
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvlad,

select distinct сильно ест дисковое пространство, если в результате запроса есть длинные поля (varchar), а записей в таблице очень много. Свободного места может и не хватить. Для запроса, который я привёл, это не критично (всего 5 млн записей и нету varchar), но есть и другие fast-таблицы.

В общем, думаю. Возможно что некоторые таблицы я буду заполнять через полный delete + insert, а часть через хитрый delete + хитрый insert.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935255
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если фаст-таблицы это что-то типа кэша-агрегатов, то мне кажется, разумно удалять тогда же, когда в них записи обновляются.
Т.е. с помощью MERGE можно залить новые/обновить какой-то признак актуальности в существующих.
Второй командой удалить неактуальные по этому признаку.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935296
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Глянул здешний список форумов, посчитал СУБД. Вместе с античностью хватает пальцев двух ног. Таки может дешевле написать для каждой нормальное решение - лефт джойн и удаление по null в хранимке? В конце концов, даже если сделать так с клиента, будет на несколько порядков быстрей, чем выполнение подзапроса для каждой записи. Как говорится, вам шашечки или ехать?
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935342
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Даже Деда разбудили, ироды. Нет, чтобы тикет соответствующий создать.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935556
ArtDen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Старый плюшевый мишка
В конце концов, даже если сделать так с клиента, будет на несколько порядков быстрей, чем выполнение подзапроса для каждой записи.

Самое смешное, что так и пришлось сделать. Оказалось, что не только fb тупит на таких запросах
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935559
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad F,

тикет о HASH OUTER JOIN зарегистрирован уже давно. Надеюсь хотя бы это мы увидим ближайшее время.

Тут по идее ещё нужны тикеты о необходимости выполнять EXISTS/IN как semi join, а NOT EXISTS/NOT IN как anti join.
Тогда будет больше вариантов оптимизации для таких запросов. И об этом ДЕ тоже известно, а вот когда руки дойдут это уже другой вопрос.
...
Рейтинг: 0 / 0
where not exists сильно тормозит
    #39935574
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ArtDen
Оказалось, что не только fb тупит на таких запросах


Естественно. Тут ведь какое дело. Все реляционные СУБД - идеологически инструмент работы с множествами. Заточены под их объединение-пересечение. И в плане модели хранения данных и в плане их использования. Начиная прямо со стандарта. Соответственно, усилия при созданиях реализаций стандарта направлены преимущественно на оптимизацию работы с множествами. И разработчик прикладухи на этом инструменте должен думать в первую очередь об эффективном использовании сильных сторон инструмента для выделения подмножества данных, над которыми должно быть выполнено какое-то действо, а не о самом действе, не запрягать телегу впереди коня. А в плане точечных уколов Btrieve Record Manager уделает любую РСУБД как дитё. Вот с ним и думать по другому надо, в первую очередь о действе.

В общем, с Международным Праздником Выноса Ёлок, мужики.
...
Рейтинг: 0 / 0
48 сообщений из 48, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / where not exists сильно тормозит
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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