Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> delete + большой обьём данных 
V
    Опции темы
cra6
Дата 10.3.2010, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.12.2007

Репутация: 2
Всего: 2



Здравстуйте.
Попросили помочь с запрососом на удаление записей.В таблице 17 млн записей.Следующий запрос выполняется очень долго.
В голову приходит обьеденить все not in в 1. Может что нибудь ещё сделать для ускорения.
Код

DELETE FROM TS_BLOBS 
WHERE TS_ID NOT IN (SELECT TS_BLOBID FROM TS_RESOURCES) 
AND TS_ID NOT IN (SELECT TS_BLOBID FROM TS_NOTIFICATIONMESSAGES)
AND TS_ID NOT IN (SELECT TS_BLOBID FROM TS_MACROS) 
AND TS_ID NOT IN (SELECT TS_BLOBID FROM TS_WSDESCRIPTIONS)



PM MAIL   Вверх
Sqlninja
Дата 10.3.2010, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 353
Регистрация: 15.5.2006
Где: San Francisco, CA

Репутация: 13
Всего: 13



Ваш SQL может работать очень по разному в зависимости от среды. Давайте начнем с описаний всех таблиц из запроса (типы, индексы, кол. строк и т.д.).


--------------------
It's better to burn out than to fade away.
PM MAIL WWW ICQ   Вверх
cra6
Дата 10.3.2010, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.12.2007

Репутация: 2
Всего: 2



Доступа к базе нет.известно что  надо удалить большинство записей.Наклепал такое
Код

create table TS_idTab as (SELECT TS_BLOBID FROM TS_RESOURCES 
union SELECT TS_BLOBID FROM TS_NOTIFICATIONMESSAGES 
union SELECT TS_BLOBID FROM TS_MACROS
union SELECT TS_BLOBID FROM TS_WSDESCRIPTIONS);

CREATE INDEX TS_idTab_index
            ON TS_idTab(TS_BLOBID);

create table TS_BlOBS_COPY NOLOGGING as(select * from TS_BLOBS where TS_ID in (select TS_BLOBID from TS_idTab));

PM MAIL   Вверх
DimW
Дата 11.3.2010, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(cra6 @  10.3.2010,  16:36 Найти цитируемый пост)
В таблице 17 млн записей

а удаляется в процентном соотнощении сколько?

Добавлено через 3 минуты и 30 секунд
Цитата(cra6 @  10.3.2010,  16:36 Найти цитируемый пост)
запрос выполняется очень долго.

это сколько?
PM MAIL ICQ   Вверх
cra6
Дата 11.3.2010, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.12.2007

Репутация: 2
Всего: 2



удалить процентов 70.
>дня.(как мне сказали)
PM MAIL   Вверх
Zloxa
Дата 12.3.2010, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



а разве вопрос еще актуален?
решение чрез create table as в подобном случае всем лучше.  Единственно, тут может окзазаться/*а может и нет*/ выгоднее использовать exists вместо in. Если же оставлять In, то возможноимело бы смысл сделать индекс уникальным.


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
azesmcar
Дата 12.3.2010, 09:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 3
Всего: 211



Цитата(cra6 @  11.3.2010,  16:55 Найти цитируемый пост)
удалить процентов 70.

не легче будет сохранить 30%, сделать truncate и заново залить в базу? заодно и дефрагментация получиться. 

Цитата(cra6 @  10.3.2010,  16:36 Найти цитируемый пост)
BLOBS 

Цитата(cra6 @  10.3.2010,  16:36 Найти цитируемый пост)
TS_ID 

уж больно названия колонок и таблиц знакомые, не TeamTrack случайно?
PM   Вверх
cra6
Дата 12.3.2010, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 10.12.2007

Репутация: 2
Всего: 2



Цитата(azesmcar @  12.3.2010,  09:51 Найти цитируемый пост)
не легче будет сохранить 30%, сделать truncate и заново залить в базу? заодно и дефрагментация получиться. 

так в принципе и сделали.
Цитата(azesmcar @  12.3.2010,  09:51 Найти цитируемый пост)
уж больно названия колонок и таблиц знакомые, не TeamTrack случайно?

он самый)
PM MAIL   Вверх
azesmcar
Дата 12.3.2010, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 3
Всего: 211



Цитата(cra6 @  12.3.2010,  20:58 Найти цитируемый пост)
он самый) 

Родной smile 

яркий пример того, как не надо проектировать базы данных, писал когда-то поддержку Tcl скриптов для него, походу изучил хорошенько их базу smile
PM   Вверх
ToshaCh
Дата 26.3.2010, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 555
Регистрация: 10.11.2005
Где: Москва, РФ

Репутация: 12
Всего: 26



Я на днях столкнулся со схожей проблемой. Разница лишь в том, что truncate нельзя сделать, т.к. сервис остановке не подлежит. 
    Короче ТЗ там было примерно такое. 
  •  Есть две базы: одна OLTP, другая аналитика (репликация на стримах).
  •  Раз в неделю с аналитики приходит инфа: данные в таблице X на OLTP базе нужно удалить. 
  •  Изначально удаляли delete'ом, но база разрослась, а это при проектировке не учли.
    Проблем сразу несколько: 
  •  Во-первых, объём. Примерно 40-60%, что соответствует нескольким миллионам записей.
  •  Во-вторых, констреинты. Таблица одна из краеугольных: на неё завязана куча дополнительной инфы (не менее 15 таблиц в дереве зависимостей), которая также очищается (благо то, что каскады нормально настроены).
  •  Ну и в-третьих база отстроена под короткие транзакции (в среднем 2Кб): маленькие буферы, небольшой undo, connection pool и т.д. 
  •  А главное сервер там куплен не для того чтобы воздух греть: загружен процентов на 80 днём и 60 ночью.

В результате я не нашёл ничего умнее чем написать джобу, которая раз в минуту просыпается, лимитированым балком выгребает список на удаление, чистит записи по одной и померает. Операция занимает около 15 секунд. Лимит искал опытным путём, смотря загрузку через EM. Получилось 5000. Таким образом это 5000*60*24=7,200,000 в сутки, что вполне достаточно до следущего вброса аналитики. Метод мне видится довольно удачным.  
    Здесь два основных параметра влияющих на производительность.
  •  Количество удаляемых записей за одну транзакцию.
  •  Время между транзакциями (читай между коммитами)
При этом второй параметр для OLTP базы не менее важен чем первый из-за склонности к высокой конкуренции на коммите. Из-за этого время между транзакциями нельзя сделать нулевым (тупо в цикле, с коммитами) или достаточно малым.




--------------------
Slackware 12.2 | Linux 2.6.27 | Fluxbox 1.1.1 | Wmii 3 | Opera 9.63 
--
Oracle это не только способ отмывания денег, но и вполне себе преличная база данных.
PM MAIL Jabber   Вверх
Zloxa
Дата 26.3.2010, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(ToshaCh @  26.3.2010,  18:01 Найти цитируемый пост)
балком выгребает список на удаление, чистит записи по одной и померает.

а не эквивалент ли это
Код

delete from test where rownum < 5000
 ?
Только это черевато тем, что всякий раз будут сканироватсья блоки ранее удаленных записей.
Лучше открывать курсор один раз а не каждый, фетчить балком, удалять форалом.
Правда есть риск свалиться по "снапшот ту олд"
Код

declare 
  c sys_refcursor;
  type tr is table of rowid;
  t tr;
begin
  open c for select rowid from test;
  loop
    fetch c bulk collect into t limit 5000;
    exit when t.count = 0;
    forall i in t.first..t.last
      delete from test where rowid = t(i);
    commit;
  end loop;
end;




Это сообщение отредактировал(а) Zloxa - 26.3.2010, 20:05


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
ToshaCh
Дата 27.3.2010, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 555
Регистрация: 10.11.2005
Где: Москва, РФ

Репутация: 12
Всего: 26



Цитата(Zloxa @  26.3.2010,  18:32 Найти цитируемый пост)
а не эквивалент ли это


Фактически да. Я такой вариант изучал. Реально там получалось: 

Код
delete from X where id in (select id from (select id from X_to_del order by id) where rownum<100);

delete from X_to_del where id in (select id from (select id from X_to_del order by id) where rownum<100);


Но мне показалось красивее и логичнее с bulk и forall. А производительность фактически одинакова. Может быть вариант с простым делетом выигрывает немного на самом удалении, но заметить я этого не смог. 



--------------------
Slackware 12.2 | Linux 2.6.27 | Fluxbox 1.1.1 | Wmii 3 | Opera 9.63 
--
Oracle это не только способ отмывания денег, но и вполне себе преличная база данных.
PM MAIL Jabber   Вверх
Zloxa
Дата 27.3.2010, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(ToshaCh @  27.3.2010,  12:57 Найти цитируемый пост)
order by id

если id индексирован и использовать для сортировки при отборе индекс /*обычно помогает хинт first_rows*/, то проблема сканирования блоков ранее удаленных записей уходит...... хотя.. range scan по разреженному индексу тоже не айс.

По сути у тебя ан один феч  два делета. Я поддерживаю тебя в том, что булкфеч с форалом эстетичнее smile Только тут фетч с фораедейтом бы делать надо.


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

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

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0819 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.