V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
vipppppp
V2EX  ›  Python

mysql(后端)分页问题

  •  
  •   vipppppp · 2018-05-31 16:47:59 +08:00 · 3372 次点击
    这是一个创建于 2375 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚刚入门没多久的后端 想请教一下,大家一般怎么做数据查询和分页问题 需要知道数据的总数( total ),以及第一页(前十条),大家一般怎么查询 想到的第一种就是查询一次总数 count(),然后在查询第 1-10 条 还有就是一口气查询全部,然后取到列表 count()得到总数,再从这么列表取第 1-10 条 因为我们项目的数据量并不大,其实怎么写问题都不大,不过还是很想了解。。。 只了解基础的 sql 语句,对复杂的不是很懂,所以想请教一下!!谢谢各位了~~

    还有一个疑问,现在我有 2 个 id,然后有个表记录日志(很多),我只想取这两个 id 最近的三十条日志,有没有直接一条 sql 语句能实现

    10 条回复    2018-06-01 18:51:45 +08:00
    DavidNineRoc
        1
    DavidNineRoc  
       2018-05-31 16:57:15 +08:00
    ## 问题 1
    $query->where()->where();
    $count = $query->count();
    $data = $query->limit()->offset()->get();
    ## 问题 2
    $query->whereIn([id1, id2])->limit(30)->get();

    ****
    楼下大神帮转换成 SQL
    qiayue
        2
    qiayue  
       2018-05-31 16:59:45 +08:00
    问题 2 是需要两个 id 各取 30 条,而不是加起来 30 条
    vimiix
        3
    vimiix  
       2018-05-31 18:03:09 +08:00
    mysql 分页的话,我一般是使用 calc_found_rows 修饰 sql:
    比如:查询第一页有 10 条数据:
    select calc_found_rows * from table where .... limit 0,10;
    获取总数直接在这条后面执行:
    select found_rows(); 就可以拿到前一条查询的总数。

    最近的三十条的话,应该是按照时间或者自增 id,逆序查询取前三十就好了吧
    select * from table where log_id in (id1, id2) order by id desc limit 30;
    dobelee
        4
    dobelee  
       2018-05-31 20:00:17 +08:00 via Android
    是的。分成兩個,一個查 count,一個查偏移數據。不過 mysql innodb 數據量大後會 count 會慢出翔,需要特殊優化。
    Mazexal
        5
    Mazexal  
       2018-05-31 22:54:33 +08:00
    数据总数获取没办法, 如果需要精确的数值只能一次查完, 不过大部分时间我们并不需求精确的记数的, 因为大数据的情况下每分每秒都在往里面插数据, 所以就算你显示出来也是当时的正确数值, 所以这里可以取巧一下, 以 1 分钟为一个单位获取总数存在缓存里, 每次只读取那一分钟定点的数值就行了.
    而且大数据情况下 limit 写法和普通写法也不一样的, mysql limit 是获取所有数据以后再抛弃不需要的数据, 所以如果你 limit 的值特别大的话会很慢, 所以这种情况一般是获取主键再回表查询的.

    至于你第二个问题, 我觉得做人没必要那么偷懒一次获取......
    InkyMountain
        6
    InkyMountain  
       2018-06-01 09:01:15 +08:00 via Android
    有个叫 pagehelper 的插件.使用前要先在 xml 里配置。

    PageHelper.offsetPage(offset, count );
    查询 sql 语句;
    int total = new PageInfo().getTotal();

    我是新手,不了解具体实现,只会使用,可以参考下。
    InkyMountain
        7
    InkyMountain  
       2018-06-01 09:21:12 +08:00 via Android
    楼上有个地方写错了,new pageinfo()要用查询结果集当参数。
    Raymon111111
        8
    Raymon111111  
       2018-06-01 10:42:39 +08:00
    count 查所有, limit offset, size 查分页数据.

    注意当 offset 特别大的时候这个方法行不通
    lilogo
        9
    lilogo  
       2018-06-01 15:19:22 +08:00
    @vimiix calc_found_rows 这种方式其实性能不好,倒不如用 count(*)
    vimiix
        10
    vimiix  
       2018-06-01 18:51:45 +08:00
    @lilogo 哦,一直在用,倒是没有关注过内部实现性能问题。请教一下,具体会有多少影响呢,到什么量级的查询量会凸现出来这个问题,谢谢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2598 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 15:27 · PVG 23:27 · LAX 07:27 · JFK 10:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.