Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Informix [игнор отключен] [закрыт для гостей] / Удаление большого объема в логируемом состоянии / 14 сообщений из 14, страница 1 из 1
25.12.2009, 14:51
    #36386659
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
Есть громадная таблица - там около миллиарда записей.
Изменение данных в рабочих таблицах привело к необходимости удаления примерно 10% записей в архивной таблице.
Сервер работает 24/7/365, поэтому перевод в нелогируемое состояние невозможен.
Отсюда - вопрос. Можно как-то штатно выполнить delete чтобы оно удаляло только какую-то часть записей? Потому что если выполнить delete сразу на весь объем удаляемых записей, то, предполагаю, что серверу станет плохо.

Приходится удалять SPL-кой по принципу
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
      select min(rowid), max(rowid)
      into   t_m1, t_m2
      from   arc_01;

      let t_c=t_m1;
      
      while t_c<t_m2
        begin work;

        delete from arc_01
        where Lid not in ValidLids and Lid<=MaximumId and rowid between t_c and t_c+ 50000 ;
        let rc=rc+DBINFO('sqlca.sqlerrd2');
        commit work;

        let t_c=t_c+ 50000 ;
      end while;

При этом поле Lid имеет индекс, но, насколько я понимаю, судя по скорости выполнения, использование rowid приводит к sequential scan, а это нереально тормозно.

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

Есть какое-то решение, как удалять записи по типу delete first 50000 from... или какой-то другой метод решения проблемы удаления большого числа записей?
...
Рейтинг: 0 / 0
25.12.2009, 15:43
    #36386831
Журавлев Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
falcon111
Сервер работает 24/7/365, поэтому перевод в нелогируемое состояние невозможен.

1. Вы не сказали версию информикса. 2. Нелогируемой можно сделать одну таблицу (raw).
3. Что такое MaximumId? Удаляйте where Lid not in ValidLids and Lid<=MaximumId and Lid >= MaximumId - 5000
...
Рейтинг: 0 / 0
25.12.2009, 15:56
    #36386854
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
Журавлев Денис1. Вы не сказали версию информикса.
Мне казалось, что здесь версия особой роли не играет. Исправляюсь.
11.50FC5 на w2003x64

Журавлев Денис2. Нелогируемой можно сделать одну таблицу (raw).
Насколько я понимаю, это приведет к ошибкам в работе добавления записей в эту таблицу, так как там записи тоже добавляются как часть общей транзакции выполнения клиентского запроса.

Журавлев Денис3. Что такое MaximumId? Удаляйте where Lid not in ValidLids and Lid<=MaximumId and Lid >= MaximumId - 5000
MaximumId - это защита от удаления записей с новыми идшниками, появившимися в системе во время выполнения процедуры удаления.

where Lid between MaximumId-5000 and MaximumId так же трудно прогнозируется число записей, по одному lid записей может быть несколько тысяч, а по другому - десятки миллионов.

Я уже подумываю выбирать lid, count(*) во временную таблицу, и потом удалять записи по ней, но все равно это будет работать до тех пор пока не возникнет необходимость удаления какого-нибудь старого объекта по которому будет много записей и все вернется к началу ;(
...
Рейтинг: 0 / 0
25.12.2009, 16:04
    #36386870
Журавлев Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
falcon111Журавлев Денис1. Вы не сказали версию информикса.
Мне казалось, что здесь версия особой роли не играет. Исправляюсь.
11.50FC5 на w2003x64ну вот например raw появились в определенной версии, а потом спустя несколько версий появилась возможность иметь индексы на raw таблицах.


falcon111Журавлев Денис2. Нелогируемой можно сделать одну таблицу (raw).
Насколько я понимаю, это приведет к ошибкам в работе добавления записей в эту таблицу, так как там записи тоже добавляются как часть общей транзакции выполнения клиентского запроса.
значит отбрасываем этот вариант.

falcon111Журавлев Денис3. Что такое MaximumId? Удаляйте where Lid not in ValidLids and Lid<=MaximumId and Lid >= MaximumId - 5000
MaximumId - это защита от удаления записей с новыми идшниками, появившимися в системе во время выполнения процедуры удаления.

where Lid between MaximumId-5000 and MaximumId так же трудно прогнозируется число записей, по одному lid записей может быть несколько тысяч, а по другому - десятки миллионов.

Я уже подумываю выбирать lid, count(*) во временную таблицу, и потом удалять записи по ней, но все равно это будет работать до тех пор пока не возникнет необходимость удаления какого-нибудь старого объекта по которому будет много записей и все вернется к началу ;(план вашего delete тогда смотрите, есть там или нет seq scan таблицы
первичный ключ суррогатный есть?
...
Рейтинг: 0 / 0
25.12.2009, 16:09
    #36386885
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
Журавлев Денис]план вашего delete тогда смотрите, есть там или нет seq scan таблицы
первичный ключ суррогатный есть?
Иными словами, штатной возможности лимитировать число удаленных записей действительно нет? Только самодельными костылями по rowid/lid/прочее? Жаль, я так надеялся что решение есть и я просто чего-то не знаю ;-)
...
Рейтинг: 0 / 0
25.12.2009, 21:42
    #36387468
zaiets
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
Почему нет? все есть, только нужно найти как єто использовать
Можно удалять все пачкой, а можно удалять по одной записи
begin work ;
foreach
select first 50000 ...
delete ...

end foreach;
commit ;

А если и есть пустой диапозон, то как он вам не мешает - ну будут пустые транзакции ну и фиг с ними.
...
Рейтинг: 0 / 0
25.12.2009, 21:57
    #36387489
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
zaietsbegin work ;
foreach
select first 50000 ...
delete ...

end foreach;
commit ;
Первый вариант был именно такой. Получается наиболее медленно. Настолько что использовать нет смысла.

zaietsА если и есть пустой диапозон, то как он вам не мешает - ну будут пустые транзакции ну и фиг с ними.
Пустые-то они ПОЛУЧАЮТСЯ пустые, только на их ПОЛУЧЕНИЕ тратятся ресурсы, время в первую очередь.

В конечном итоге решил выборкой lid, count(*) во временную таблицу, потом группирую идшники так чтобы получить максимально приближенное число записей к желаемому в пределах одной транзакции и удаляю по одному только индексированному lid - получается наиболее быстро.

Решение всем бы красивое, если бы не непонятки с "массивными" lid-шниками. Если подскажете более практичное решение - буду благодарен :)
...
Рейтинг: 0 / 0
27.12.2009, 00:39
    #36388253
zaiets
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
Вы сами нашли решение, которое наиболее устраивает вас по скорости.
По поводу "массивных" - ничего сложного не вижу.
Вычислите какая максимально возможна массивность для вашей конфигурации и подберите соответствующий диапозон для удаления.

В принципе,если делаете через временную таблицу, для временной таблицы можно сделать поле сериал и после помещения данных в таблицу в процедуре реализовать алгоритм подсчета коунтов
и дробления записей для удаления.

Чем вызвано ваше ограничение по времени?

у меня обычно задача стояла как-бы немного замедленнить эту операцию - запустить в фоне и пускай работает особо никому не мешая.
...
Рейтинг: 0 / 0
28.12.2009, 08:54
    #36389200
Журавлев Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
falcon111Пустые-то они ПОЛУЧАЮТСЯ пустые, только на их ПОЛУЧЕНИЕ тратятся ресурсы, время в первую очередь.
ну нам что-ли покажите план запроса.
...
Рейтинг: 0 / 0
28.12.2009, 21:00
    #36390803
Выбегалло
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
Ну вы даете.
На хрена один и тот же запрос гонять тысячи раз ?
Пишите SP вида :

declare i, vsp int;

let i = 0;
begin work;
foreach cur1 with hold for <select condition for deleted records>
delete from arc_01 where current of cur1;
let i = i +1;
if i > 5000 then
let i = 0;
commit work;
begin work;
end foreach;

commit work;
...
Рейтинг: 0 / 0
29.12.2009, 17:05
    #36392496
Евгений Фадеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
ВыбегаллоНу вы даете.
На хрена один и тот же запрос гонять тысячи раз ?
Пишите SP вида :

declare i, vsp int;

let i = 0;
begin work;
foreach cur1 with hold for <select condition for deleted records>
delete from arc_01 where current of cur1;
let i = i +1;
if i > 5000 then
let i = 0;
commit work;
begin work;
endif
end foreach;

commit work;
...
Рейтинг: 0 / 0
29.12.2009, 17:52
    #36392685
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
ВыбегаллоНу вы даете.
На хрена один и тот же запрос гонять тысячи раз ?Потому и обратился за помощью, что это не правильно :)
Выбегаллоdelete from arc_01 where current of cur1;Вот оно! Это и был судя по всему тот самый пробел в моих познаниях, я не знал, что в foreach можно так использовать выбранные строки, и мне, кстати, частенько этой возможности не хватало.
Теперь тема раскрыта полностью, огромное спасибо!! :-)

PS: А с какой версии существует where current of ?
...
Рейтинг: 0 / 0
29.12.2009, 17:59
    #36392712
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
falcon111
PS: А с какой версии существует where current of ?

В 7.31 уже был точно. Достаточно? :)
...
Рейтинг: 0 / 0
29.12.2009, 18:04
    #36392727
falcon111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление большого объема в логируемом состоянии
АнатоЛойfalcon111
PS: А с какой версии существует where current of ?

В 7.31 уже был точно. Достаточно? :)

Да *стыдливо ковыряя ботинком землю* ;-))

Пошел посмотрю PDFку на предмет аналогичных дырок в моей голове :)
...
Рейтинг: 0 / 0
Форумы / Informix [игнор отключен] [закрыт для гостей] / Удаление большого объема в логируемом состоянии / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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