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


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