用 ORM 查询数据 Pagination 分页时,点击下一页 page=2 时,还会再读数据库( MySQL)吗?

2017-03-25 09:13:13 +08:00
 rogwan
用 ORM 分页查询数据,比如查出来有 10 页数据,这 10 页数据是一次性从数据库( MySQL )读出来,放在内存里?

还是其实 ORM 只是把 page=1 的数据读出来了?然后点击 page=2 时,还要再去数据库( MySQL )读一次数据?
2690 次点击
所在节点    问与答
15 条回复
bonfy
2017-03-25 09:19:30 +08:00
我猜是后者 orm 打印出 sql 看看呗

你要放内存自己弄个 list 存呗
yangqi
2017-03-25 09:20:37 +08:00
是 mysql 里面的分页, LIMIT offset, count
msg7086
2017-03-25 09:34:30 +08:00
ORM 是不会放在内存里的。
一来内存就炸了。
二来数据被修改了怎么办。
一般都是要多少读多少,显示完以后当场丢弃。
mcfog
2017-03-25 09:51:21 +08:00
先搞清楚什么是 ORM 什么是 Pagination 什么是数据库,再来重新提问吧
ivvei
2017-03-25 09:54:17 +08:00
这得看你 ORM 怎么写的啊。你要写成一次取完之后都是缓存也可以的啊,只是一般人不是这么干的而已。
sorra
2017-03-25 09:54:36 +08:00
复习一下分页查询 https://www.qingjingjie.com/blogs/24
通常是每页读一次的。如果是 Java 的 Hibernate ,它有预读功能,比如翻一页读取两页。
如果全读出来,就不用 ORM 分页了,你自己取 sub list 就可以。
liteyou
2017-03-25 10:47:25 +08:00
@mcfog 有很多小白未必清楚 ORM 的内部逻辑,这个问题没毛病
mcfog
2017-03-25 12:45:47 +08:00
@liteyou 如果只是不清楚内部逻辑,提问方式应该是“ Laravel/Django/RoR 的分页机制是如何拉取数据的?是每次拉当前页还是一次性全部拉出来然后分页?“

首先分页这个事情是框架调用 orm 实现的,怎么实现是框架的问题。其次是 orm 只是个总称,这样问就好像问“下棋的时候第一步怎么走好?”一样,让别人很难回答,也许只能回答“怎么走胜率高就怎么走”,楼主这个问题也只能说“有的是这样实现的,有的是那样实现的,还有的几种都支持”
liteyou
2017-03-25 17:07:12 +08:00
@mcfog 这么几个回复, 4 人收藏,说明还是很多人有这个疑问吧。
rogwan
2017-03-26 13:56:12 +08:00
@yangqi
@msg7086
@sorra

感谢!这样子的话, ORM (比如 SQLAlchemy )的 Pagination 分页用的是 limit().offset(),那要是 ORM 一次查询出来 MySQL 返回了 1000 条记录,但我只想要 300 条数据就够了,是不是用了 Pagination ,就不能再用 limit()了?

用了 ORM 的 Pagination ,但只想要返回 300 条数据,有什么方法吗?
sorra
2017-03-26 14:58:16 +08:00
@rogwan 那不就是 limit 设为 300 么。要想再往后取就设 offset 。
至于 Pagination 和 limit()能不能重复用,不了解 SQLAlchemy ,可能是后调用的覆盖先调用的,也可能报错。风格上不宜重复。
msg7086
2017-03-26 15:18:11 +08:00
@rogwan 用了分页的话,只会返回比如 20 条数据,哪来的 300 条。 300 条一页这页面不得炸了。
msg7086
2017-03-26 15:22:01 +08:00
拿 Rails 举个例子。

你说返回 300 是这个情况:
Post.limit(300) #=> 300 条数据
SELECT * FROM Post LIMIT 300

实际上,假如 page 大小是 20 的话:
Post.page(4) #=> 20 条数据
SELECT * FROM Post LIMIT 60,20

点了下一页:
Post.page(5) #=> 20 条数据
SELECT * FROM Post LIMIT 80,20

不知道能不能让你理解。
yangqi
2017-03-26 22:23:30 +08:00
@rogwan ORM 里面的 limit()和 offset()最后都是转化成 mysql 查询的 limit 的,所以返回 1000 条就不能再 limit 了,只能在代码里面处理。
rogwan
2017-03-27 10:03:37 +08:00
谢谢,去设置下试试看。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/350186

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX