点击上方 好好学java ,选择 星标 公众号
重磅资讯,干货,第一时间送达 明天的建议:
个人原创100W +访问量博客:点击前往,查看更多 翻译:高可用架构(ArchNotes)
对于设计和实现 API 而言,当结果集包含数万条记录时,返回查询的所有结果可能是一个挑战,这会给服务器、客户端和网络带来不必要的压力。 具有分页功能。
一般我们使用偏移量offset或者footer来进行分页,然后通过API实现类似的请求:
GET /api/products?page=10
{"items": [...100 products]}如果想继续访问后续数据,只需更改分页参数即可。
GET /api/products?page=11
{"items": [...another 100 products]}使用offset时,一般使用大家熟悉的?offset=1000和?offset=1100这两个方法。 它要么直接调用OFFSET1000LIMIT100的SQL查询数据库,要么使用LIMIT除以页作为查询参数。
无论如何,“这是一个次优解决方案”,因为无论哪个数据库都必须跳过上面偏移量指定的 1000 行。 当跳过额外的偏移量时elementui图片分页显示,无论是 PostgreSQL、ElasticSearch 还是 MongoDB,都会产生额外的费用。 数据库需要对它们进行排序和统计elementui图片分页显示,然后丢弃后面不再使用的数据。
这是一种效率低下的方式,但由于使用简单,所以你会反复使用这种方式,即直接将API参数映射到数据库查询。
适当的方法有哪些? 在介绍之前我们可以先看一下数据库的实现。 数据库中有一个游标的概念,它是指向一行的表指针。 然后您可以告诉数据库:“返回此游标之后的 100 行。” 此命令对于数据库来说很容易,因为您可能可以通过索引数组来识别行。 那么就不需要检索和跳过上述未使用的记录。
举个反例。
GET /api/products
{"items": [...100 products],
"cursor": "qWe"}API 返回一个无业务意义的字符串(光标),您可以使用它来检索下一页。
GET /api/products?cursor=qWe
{"items": [...100 products],
"cursor": "qWr"}有许多技术可以实现游标。 一般来说,这可以通过一些排序数组(例如产品id)来实现。 在这些情况下,您可以使用某种可逆算法对产品 ID 进行编码。 当您收到带有游标的请求时,您可以对其进行解码并生成类似 WHEREid>:cursorLIMIT100 的查询。
下面是一个小小的性能对比,首先看看offset是如何工作的:
=# explain analyze select id from product offset 10000 limit 100;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Limit (cost=1114.26..1125.40 rows=100 width=4) (actual time=39.431..39.561 rows=100 loops=1)
-> Seq Scan on product (cost=0.00..1274406.22 rows=11437243 width=4) (actual time=0.015..39.123 rows=10100 loops=1)
Planning Time: 0.117 ms
Execution Time: 39.589 ms让我们看看 where(cursor) 语句是如何工作的:
=# explain analyze select id from product where id > 10000 limit 100;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..11.40 rows=100 width=4) (actual time=0.016..0.067 rows=100 loops=1)
-> Seq Scan on product (cost=0.00..1302999.32 rows=11429082 width=4) (actual time=0.015..0.052 rows=100 loops=1)
Filter: (id > 10000)
Planning Time: 0.164 ms
Execution Time: 0.094 ms这可是好几个数量级的差距啊! 事实上,实际差异取决于表的大小以及过滤器和存储的实现。 有一篇很好的文章(1)提供了更多的技术信息,上面有ppt,性能对比在42号Magic KT Board中展示。
(1)
事实上,用户不会通过ID来检索产品,而是会根据一些相关性进行查询(然后将ID作为关联数组)。 在现实世界中,您需要根据您的业务决定做什么。 订单可以按 id 排序(因为它是单调递减的)。 订单列表可以按心愿单时间排序。 在我们的例子中,该产品来自ElasticSearch,它天然支持光标功能。
我们可以看到的一个缺点是,使用无状态API很难支持诸如转到“上一页”之类的功能。 因此,在面向用户的界面中,如果有上一页/下一页或者“直接到第10页”等按钮,就没有办法绕过上面提到的offset/limit实现。 在其他情况下,使用基于游标的分页可以极大地提高性能,特别是在非常大的表和非常深的分页上。
英文原文:
常见问题
相关文章
猜你喜欢
- elementui change传参数-关于elementUI中表单组件的二次封装 2024-04-29
- elementui分页组件复用-Vue+Element UI+Lumen实现万能表格分页功能 2024-04-28
- elementui表格导入导出-vue+element导入excel数据并转换为json存入el-table 2024-04-27
- 重写elementui部分方法-uni-app黑魔法探索(一)——重写外部标签 2024-04-27
- elementui 顶部导航菜单-ElementUI底部菜单响应式实现 2024-04-27
- elementui树形拖拽排序-Elementui表格组件+sortablejs示例代码实现行拖拽排序 2024-04-27
- 实现模糊查询elementui-UI手动测试Selenium——css和xpath有什么区别? 2024-04-23
- elementui表格循环编号-使用v-for循环遍历element-ui的表 2024-04-23
- elementui数值范围控件-elementUI 表单验证 v 2024-04-10
- elementUI中有哪些组件-ElementUI:丰富多彩、易于使用且高效的前端组件库 2024-04-09