分页和排序问题

Posted

技术标签:

【中文标题】分页和排序问题【英文标题】:Issues with pagination and sorting 【发布时间】:2010-11-05 01:55:20 【问题描述】:

我正在研究面向数据库的 Web 应用程序中的情况,当人们应该依赖于客户端的表排序而不是服务器端的排序时。困扰我的一种特殊情况是分页。

当尝试对大表(例如 10000 行)进行分页以及按特定列对其进行排序时,最好的方法是什么?

我了解与此相关的一些问题是:

我无法一次性将整个表返回客户端 我无法使用 javascript 对多达 10000 条记录进行排序 对表格进行排序将涉及对所有页面中的行进行排序,而不仅仅是当前页面。

那么您还有其他问题要添加到此列表中吗?

什么方法可以很好地混合客户端和服务器端交互,从而最大限度地减少服务器负载?


补充:

好的,对数据库进行排序并返回reqd页面,上一页和下一页似乎是最好的选择。

现在考虑一下:

用户在按序列号排序的表格的第 3 页(共 10 页)上。现在用户单击名为“用户名”的标题,希望按用户名对表格进行排序。

问题:最终结果应该是“按用户名排序的第 1 页,共 10 页”还是“按用户名排序的第 3 页,共 10 页”?

我知道这是一个非常主观的问题,但您会推荐什么以及为什么?

【问题讨论】:

好问题。你可能会说我最近处理了这个[问题。 【参考方案1】:

客户端最好保持简单:Javascript 排序/分页仅适用于非常小的结果集 - 小到用户不会注意到性能下降。

服务器端是您可以优化服务器负载的地方:

负载可能以频繁请​​求更多页面、每页大量行/列以及频繁请求重新排序的形式出现。 (我们还没有谈到过滤)

因此,根据您的用户和实际使用情况,您可能需要某种形式的缓存。请注意,这些是在您知道用户在做什么之后的一段时间内的建议:

对于频繁的页面请求,考虑让一些 Ajax 请求预加载接下来的几个(和之前的)页面,然后根据用户请求将行(通过 Javascript)交换到表中。

对于较大的页面大小,请考虑将行保存在“最近使用的”应用程序(内存)缓存中,这样数据库就不需要一遍又一遍地吐出相同的大块数据.

对于频繁使用,一个好的方法是在 SQL 中保留一个只包含结果的缓存表。

总是,总是,总是适当地索引数据库。


补充回复:

我非常主观的反应是:用户(我)想从任意页面排序。让他们(我)。没有什么比在你想去的地方更烦人的了,让一个应用程序让你回到列表的开头。

另外一个考虑是多级排序:你想实现先按序号排序,然后按用户名排序吗?考虑 Microsoft Excel 的功能,或您的用户熟悉的任何其他应用程序。您的用户可能会对他们习惯的内容感到满意 - 包括被退回到第 1 页。

【讨论】:

【参考方案2】:

数据库在数据排序和选择方面是真正的野兽。所以你最好的选择肯定是让客户端对服务器说,“我想要页面 X,其中 Y 行按 Z 排序。”然后数据库做它的事情,客户端显示结果。为了提高性能,您可以让客户端缓存结果,此外,您可以在获取当前页面后让代码请求下一页和上一页,以便在请求时立即显示它们。

【讨论】:

【参考方案3】:

最好的方法是在数据库级别进行排序和分页,只返回原始数据的一个子集,这些数据只会显示在屏幕上。在这种情况下没有 javascript。

如果由于某些原因您无法在数据库级别进行排序和分页,那么您应该使用服务器端脚本来完成。在这种情况下也没有 javascript。

最糟糕的方法是使用 javascript 进行排序和分页,出于显而易见的原因,这当然完全不推荐。

【讨论】:

【参考方案4】:

让数据库对传递到屏幕上特定页面的内容进行排序。它几乎总是更快、被缓存并减轻浏览器上的这种负载。

如果您愿意,如果数据足够详细并且可以从中受益,让客户端允许通过 javascript 等进行进一步的子排序。您可能想要存储子排序功能是什么选择以便在页面之间记住它们。

【讨论】:

以上是关于分页和排序问题的主要内容,如果未能解决你的问题,请参考以下文章

jqgrid能前台分页么?jqgrid前端分页和排序的实现

Angular Material 表的问题 - 分页和排序

分页和排序

laravel分页和排序表

在 oracle 中使用存储过程进行分页和排序

Spring Data Cassandra 中的分页和排序查询