powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / where not exists сильно тормозит
25 сообщений из 48, страница 1 из 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
25 сообщений из 48, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / where not exists сильно тормозит
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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