V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
rogwan
V2EX  ›  问与答

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

  •  
  •   rogwan · 2017-03-25 09:13:13 +08:00 via Android · 2680 次点击
    这是一个创建于 2561 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用 ORM 分页查询数据,比如查出来有 10 页数据,这 10 页数据是一次性从数据库( MySQL )读出来,放在内存里?

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

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

    首先分页这个事情是框架调用 orm 实现的,怎么实现是框架的问题。其次是 orm 只是个总称,这样问就好像问“下棋的时候第一步怎么走好?”一样,让别人很难回答,也许只能回答“怎么走胜率高就怎么走”,楼主这个问题也只能说“有的是这样实现的,有的是那样实现的,还有的几种都支持”
    liteyou
        9
    liteyou  
       2017-03-25 17:07:12 +08:00 via Android
    @mcfog 这么几个回复, 4 人收藏,说明还是很多人有这个疑问吧。
    rogwan
        10
    rogwan  
    OP
       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
        11
    sorra  
       2017-03-26 14:58:16 +08:00   ❤️ 1
    @rogwan 那不就是 limit 设为 300 么。要想再往后取就设 offset 。
    至于 Pagination 和 limit()能不能重复用,不了解 SQLAlchemy ,可能是后调用的覆盖先调用的,也可能报错。风格上不宜重复。
    msg7086
        12
    msg7086  
       2017-03-26 15:18:11 +08:00
    @rogwan 用了分页的话,只会返回比如 20 条数据,哪来的 300 条。 300 条一页这页面不得炸了。
    msg7086
        13
    msg7086  
       2017-03-26 15:22:01 +08:00   ❤️ 1
    拿 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
        14
    yangqi  
       2017-03-26 22:23:30 +08:00   ❤️ 1
    @rogwan ORM 里面的 limit()和 offset()最后都是转化成 mysql 查询的 limit 的,所以返回 1000 条就不能再 limit 了,只能在代码里面处理。
    rogwan
        15
    rogwan  
    OP
       2017-03-27 10:03:37 +08:00
    谢谢,去设置下试试看。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5443 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 08:51 · PVG 16:51 · LAX 01:51 · JFK 04:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.