为此使用Sybase ASE 15 - 我定期从表中删除大量行(最多10 mil),但我想保留对表中最新添加的数据的选择,所以规则直接在表上使用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...
或者我对其他方法持开放态度!
答案 0 :(得分:1)
可能你最好的解决方案是使用分区。
我不知道Sybase上的分区细节,但是,如果您可以创建基于时间的分区,则可以通过更改分区来删除它们。
但是,您需要创建未来分区并删除旧分区的东西 - 这是您必须维护的一个软件(它可能是在数据库服务器上运行的存储过程或脚本或“cron”上的其他位置“工作等等。”
您还需要确保正确删除node_type ='X'的那些。
也许你可以创建两组日常分区,一组用于node_type ='X',另一组用于其他node_types,并且每天创建新分区(明天,也许是后一天)并删除旧的分区如果您确实需要数据,则需要或合并它们。
答案 1 :(得分: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
答案 2 :(得分:0)
根据您的具体情况,快速bcp可以使插件快速运行。 这将改变您的整体设计需要一个shell脚本(或批处理文件),但它可以工作(如果您的表设计为允许快速BCP)
要看的另一件事是为什么插入很慢。是磁盘问题吗?需要更新的索引太多了?可能的情况是,对数据库结构进行某些调整可以加快速度。