我有一个电信计费软件系统.其中包含用户呼叫的每日日志.日志按日期(月)水平分区.每个分区都存储在一个单独的数据库中,可以分布在多个实例上.
在UI中,用户将指定日期范围.返回的数据可以在任何字段上排序.日期范围可能跨越多个分区.应用程序必须支持通过日期范围的数据进行分页.
我无法将太多记录加载到内存中进行排序.在查询中放置排序只能在一个结果集中提供排序数据.
所以我需要对多个分区中的数据进行排序,每个分区都是单独排序的如何从多个排序结果集中将已排序记录返回到UI?
解决方法:
听起来你的架构已经过了分区并且是分片的.如果您有系统软件或应用程序框架,可以处理应该实现此要求的分片.
为了获得正确的排序顺序,您必须同时在同一位置获得所有相关分片的结果.无法从一个分片获得一些结果,然后从另一个分片获得更多结果,并且能够保证用户可以选择的任何排序顺序.
一种方式(如BriteSponge建议的那样)将定义一个跨越所有分片的视图.让DBMS处理编组各种分片结果集的复杂性.如果可以管理,这将是我的首选解决方案.它将应用程序与数据库实现细节分开.
如果你必须自己写这个,你有一些希望,你有分页.这将限制您将在UI中显示的最大数量或行,因此,必须从每个分片返回的最大行数.从日期范围开始,您可以确定需要哪些分片.对每个分片,您提交表单的查询
select <columns>
from <table>
where date between <start> and <end>
order by <user selection>
fetch first <number> rows only
< number>将是您要在UI中的单个页面中显示的最大行数.虽然它们不太可能全部来自一个碎片,但它是可能的,这是限制必须的.
如果您的Oracle版本不支持最终限制条款,则以下内容仍然有效,但效率会低得多.
在结果集上执行多向合并.当您达到UI中一个页面的限制时停止.丢弃结果集的其余部分.
当用户向前翻页时,使用标准分页技术重新提交SELECT.
当用户选择不同的排序顺序时,修改SQL以匹配并重新提交到每个分片.
我的偏好是在存储过程中实现此服务器端.这将使应用程序和存储尽可能分开.此外,不是多路合并,各种结果集都可以进入单个工作表,然后对其进行排序,并将正确的行数返回给应用程序.
如果您确实在客户端实现它,而不是丢弃结果集的未使用部分,则可以缓存它们.这可能以额外的复杂性为代价减少后续页面的负载.