Выборочное удаление больших объемов данных из таблицы Sybase - PullRequest
1 голос
/ 10 сентября 2010

Использование Sybase ASE 15 для этого - у меня есть большое количество строк (до 10 милов), которые необходимо регулярно удалять из таблицы, но я хочу сохранить выбор последних добавленных данных в таблицу,так что исключается использование truncate непосредственно для таблицы.

delete from master_table where...

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

1) select * into #temp_table from master_table where date_updated > dateadd(mi, -15, getdate()) and node_type != 'X'
2) truncate table master_table
3) insert into master_table select * from #temp_table

Это достаточно хорошо - 1 и 2 имеют отличную производительность, но вставка обратно в мастер слишком медленная.

Так что мой вопрос действительно сводится к тому, есть ли быстрый способ сделать одно из:

delete from master_table where...
insert into xyz select * from...

Или я открыт для альтернативных подходов!

Ответы [ 3 ]

1 голос
/ 18 января 2011

Копирование из master_table (в temp_table) выполняется быстро, но копирование этих строк обратно в master_table выполняется медленно. Итак, у вас есть индексы, ограничения и триггеры на master_table. Возможно, вам придется взглянуть на них, чтобы увидеть, действительно ли они нужны для таблицы, которая используется для массовых вставок и удалений «на регулярной основе», и найти альтернативы в зависимости от потребностей вашего бизнеса.

В приведенном ниже решении предполагается, что master_table не имеет никаких зависимостей или ограничений. Поскольку вы делаете это «на регулярной основе» и в любом случае удаляете большинство строк master_table, будет быстрее использовать постоянную temp_table.

-- Create the copy table, for the first run
-- if not exists
create table master_table_copy         -- This is your permanent temp_table
as select * from master_table where 1=2

-- Copy rows you want to keep
insert into master_table_copy
select * from master_table
where date_updated > dateadd(mi, -15, getdate())
and node_type != 'X'

truncate table master_table

-- Rename the tables
exec sp_rename 'master_table', 'master_table_orig'
exec sp_rename 'master_table_copy', 'master_table'
exec sp_rename 'master_table_orig', 'master_table_copy'   -- use for next time
1 голос
/ 10 сентября 2010

Вероятно, ваше лучшее решение - использовать разбиение.

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

Однако вам понадобится что-то, что создает будущие разделы и удаляет старые - это часть программного обеспечения, которую вы должны поддерживать (это может быть хранимая процедура или сценарий, который запускается на сервере базы данных или в другом месте на «cron»). "работа и т. д.).

Вам также необходимо убедиться, что те, у кого node_type = 'X', удалены правильно.

Может быть, вы можете создать два набора ежедневных разделов, один для node_type = 'X', а другой для других node_types, и создавать новые разделы каждый день (на завтра и, возможно, на следующий день) и отбрасывать старые, которые у вас нет ' не нужно или объедините их, если вам нужны данные.

0 голосов
/ 11 сентября 2010

В зависимости от ваших обстоятельств быстрый bcp может сработать, чтобы ускорить вставку. Это изменит ваш общий дизайн и потребует сценария оболочки (или пакетного файла), но он может сработать (если ваша таблица предназначена для быстрого BCP)

Другая вещь, на которую стоит обратить внимание: , почему вставка медленная. Это проблемы с диском? Слишком много индексов нужно обновить? Может случиться так, что некоторые изменения в вашей структуре базы данных могут ускорить ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...