如何解决在数据库或Web应用程序中进行分页选择
| 我正在考虑重新制作我们网站的报告页面,以便更快,而且我对应该如何实现分页也持谨慎态度。我们的数据库很大,有超过1.5亿条记录。我们的大多数报告都需要多达5到10个表的复杂数据,因此每个表可能具有5或6个联接和一些内部选择。显然,它们不是快速查询。 为了在数据库端实现分页,对于每个Web请求,我需要在数据库中查询当前页面的行数(例如10,000中的100),但是我还必须再次查询数据库以获取可能的行总数。结果,我实际上对整个查询运行了两次,因为要获取记录总数的查询仍然需要执行所有联接和内部选择以确定总数。 一次运行查询,返回所有结果,将其缓存在会话中并使用Web代码对其进行分页会更好吗?我知道我最初会提取更多数据,但是我只运行一次查询,该查询可能需要30到60秒一次而不是两次。 这是一个技术通用问题,但万一重要,我将使用.net 4.0和Oracle 11g。解决方法
您可以使用以下分析功能与分页的行同时获取行数:
SELECT [cols],nb_rows
FROM (SELECT [cols],nb_rows,rownum r
FROM (SELECT [cols],count(*) over() nb_rows
FROM [your_query])
WHERE rownum <= :M)
WHERE r >= :N
这样可以确保您只运行一次查询,并且对网络带宽的压力较小。
有关更多分析,请参见Oracle中分页查询的速度。
如果满足以下条件,则缓存整个查询的结果可能很有意义:
用户可以在结果集中定期向前/向后移动,而无需刷新数据
网络带宽和可用内存(应用程序侧)就足够了(最有可能只有在同时用户数量保持较小的情况下才有可能)
, 根据我的经验,如果留给数据库,分页总是更快。毕竟,数据库是用来查询和处理大量数据的。
如果您在.NET中返回大量数据并在会话中对其进行“缓存”,则会很快耗尽服务器上的内存。
, 在数据库中执行。对于Oracle,您可以尝试以下方法:
select *
from ( select a.*,rownum r
from ( select *
from t
where x = :host_variable
order by y ) a
where rownum <= :HigherBound )
where r >= :LowerBound
其中LowerBound和HigherBound定义了页面边界(对于第1页,每页显示10个,您将具有Lower = 1和Higher = 10)
这里的窍门是:
确保按顺序排序的内部选择相当快(使用适当的索引)。
使用rownum可以使Oracle做一个停止键,这有助于限制它需要处理的行。
对于您的情况,如果您有一个复杂的查询需要花费一些时间才能运行并返回大量数据,则肯定要先创建一个物化视图,添加一个或两个索引以支持对快照表的查询,然后在需要时刷新完成。您上面的查询将来自mat视图,而不是来自基表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。