我有一个相对较大的表(约100米记录),它基本上是一个XML存储。可以存在具有不同时间戳的多个XML文档(具有最新时间戳=最新版本的逻辑)。我们期待每月批量更新的数据,可能是新版本的~70%的数据。
我们计划只在商店中保留最近的2-3个版本,所以我猜我们当前的b-tree索引(记录ID,时间戳)不一定是最快的?一个直接的“select * from table of time time time> = yyyy-mm-dd order by record id,timestamp”查询花了15个小时才能完成昨晚 - 相当高规格的套件,我不认为其他人在使用当时的DB。
(重新:查询本身,理想情况下我只想选择时间戳> = yyyy-mm-dd的最新文档,但现在这不是问题了。)
有什么方法可以创建auto- 减量列,如下所示:
Record ID Timestamp Version XML
1 2011-10-18 1 <...>
1 2011-10-11 2 <...>
1 2011-10-04 3 <...>
2 2011-10-18 1 <...>
2 2011-10-11 2 <...>
等等 - 即随着新版本的出现,最新的时间戳=版本1,所有较旧的记录获得版本=版本+ 1.这样我的管家脚本可以是一个简单的“删除版本&gt ; 3“(或我们决定保留的任何东西),我可以在记录ID上有一个b树索引,在版本上有二进制索引吗?
希望我没有完全咆哮错误的树 - 整个早上一直“创造性地谷歌搜索”,这就是我提出的理论......
答案 0 :(得分:0)
我不确定减少版本是个好主意。唯一的方法是使用触发器查找匹配的记录ID并相应地更新它们。这对性能来说不是很好。
这就是我在数据库环境(类似大小)中做类似事情的方法。希望它有用:
创建一个单独的存档表,其中包含所有版本的记录。这将由插入主表的触发器填充。触发器将insert
当前版本的记录存入您的存档,并update
主表上的记录,增加版本号并更新时间戳和数据。
然后,当您只需要选择所有记录的最新版本时,您只需执行以下操作:
SELECT * FROM TABLE;
如果您需要能够查看数据在给定时间点的查看方式的“快照”,则表格中还需要valid_from
和valid_to
列来记录数据的时间。每个版本的记录都是最新版本。您可以在写入存档表时使用触发器填充这些内容。
Valid_to
可以设置为可用的最大日期。当插入更新版本的记录时,您将先前版本的valid_to
更新为新记录的valid_from
之前(为了避免欺骗而不一样).. < / p>
然后,当您想要查看数据在给定时间的外观时,可以使用SQL查询存档表,如:
SELECT *
FROM ARCHIVE_TABLE a
WHERE <time you're interested in> BETWEEN a.valid_from AND a.valid_to
答案 1 :(得分:0)
批处理工作肯定不同于典型的插入/更新方法(特别是如果涉及触发器或许多索引)。即使使用了不错的磁盘/硬件,你也会发现传统的DML方法在这个卷上非常慢。对于每月更新70毫米的100毫米+表,我建议采用类似的方法:
将新批处理文件(70mm)加载到单独的表(NEW_XML)中,格式与现有表格(EXISTING_XML)相同。使用nologging以避免撤消。
追加(nologging)EXISTING_XML中NEW_XML中不存在的记录(30mm recs,基于您已使用的任何键)。
将EXISTING_XML重命名为HISTORY_XML,将NEW_XML重命名为EXISTING_XML。在这里,您可能需要一些停机时间,也许需要一个周末的休息时间。这不会花费任何时间,但您需要时间进行下一步(并且由于对象失效)。如果您已经拥有上个月的HISTORY_XML,请先截断并删除它(保留1个月的旧数据)。
在EXISTING_XML上构建索引,统计信息,约束等(现在也包含新数据)。重新编译任何无效的对象,使用日志记录等
简而言之,您将拥有一个表(EXISTING_XML),它不仅具有新数据,而且构建相对较快(比DML /触发方法快许多倍)。此外,如果需要,您可以尝试使用并行执行步骤2。
希望有所帮助。