我正在考虑将网站的报告页面重新设计得更快,而且我正在研究如何实现分页。我们的数据库很大,> 1.5亿条记录。我们的大多数报告都需要来自最多5到10个表的复杂数据,因此每个表可能有5个或6个连接以及一些内部选择。显然,它们不是快速查询。
要在数据库端实现分页,对于每个Web请求,我需要在数据库中查询当前页面的行(例如100个中的100个),但我还需要再次查询数据库以获取总数可能的行。因此,我基本上运行整个查询两次,因为获取记录总数的查询仍然需要执行所有连接和内部选择以确定总数。
运行查询一次,返回所有结果,将其缓存在会话中,并使用Web代码进行分页是不是更好?我知道我最初会提取更多数据,但我只运行一次可能需要30到60秒而不是两次的查询。
这是一种技术通用问题,但如果重要,我使用.net 4.0和Oracle 11g。
答案 0 :(得分:3)
您可以使用以下分析获取与分页行同时的行数:
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
这将确保您只运行一次查询,并减轻您的网络带宽压力。
有关进一步分析,请参阅Speed of paged queries in Oracle。
在以下情况下缓存整个查询的结果可能有意义:
答案 1 :(得分:3)
根据我的经验,如果留给数据库,分页总是更快。毕竟构建了一个数据库来查询和操作大量数据。
如果您在.NET中返回大量数据并在会话中“缓存”它,您的服务器上的内存将很快耗尽。
答案 2 :(得分:1)
在数据库中执行此操作。对于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个,您有更低= 1和更高= 10)
这里的诀窍是:
至于你的情况,如果你有一个复杂的查询,需要时间来运行并返回大量的数据,你肯定想先创建一个物化视图,添加索引或两个支持快照表上的查询,然后在需要时刷新完成。您上面的查询将来自mat视图,而不是来自基表。