1

为此使用 Sybase ASE 15 - 我有大约大量的行(最多 10 百万)要定期从表中删除,但我想将最新添加的数据选择保留到表中,以便规则直接在表上使用截断。

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...

或者我对替代方法持开放态度!

4

3 回答 3

1

可能您最好的解决方案是使用分区。

我不知道 Sybase 上分区的详细信息,但是,如果您可以创建基于时间的分区,则可以通过更改分区来删除它们。

但是,您将需要一些可以创建未来分区并删除旧分区的东西 - 这是您必须维护的一个软件(它可能是在数据库服务器或“cron”作业的其他地方运行的存储过程或脚本等)。

您还需要确保那些 node_type='X' 被正确删除。

也许您可以创建两组每日分区,一组用于 node_type='X',另一组用于其他 node_types,并且每天(明天,也许后天)创建新分区并删除不需要的旧分区,如果您确实需要数据,或者合并它们。

于 2010-09-10T14:33:01.537 回答
1

从 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
于 2011-01-18T18:10:39.103 回答
0

根据您的情况,快速 bcp 可以使插入快速运行。这会将您的整体设计更改为需要一个 shell 脚本(或批处理文件),但它可以工作(如果您的表设计为允许快速 BCP)

要查看的另一件事是插入速度慢的原因。是磁盘问题吗?需要更新的索引太多?对数据库结构进行某些调整可能会加快速度。

于 2010-09-11T04:45:59.340 回答