精华内容
下载资源
问答
  • mySQLmysql 分页查询

    万次阅读 多人点赞 2019-05-05 14:36:37
    MySQL:limit分页公式、总页数公式 1) limit分页公式 (1)limit分页公式:curPage是当前第几页;pageSize是一页多少条记录 limit (curPage-1)*pageSize,pageSize (2)用的地方:sql语句中 select * from student...

    目录

    一、limit分页公式、总页数公式

    1 limit分页公式

    2 总页数公式

    二 、Mysql的三种分页方法

    1 limit m,n分页语句(低效)

    2 limit m语句 (有局限)

    三、 查询优化

    1 使用子查询优化

    2 使用 id 限定优化(前提:id是连续递增,删除过记录不符合)

    3 使用临时表优化

    四、关于数据表的id说明

    五、欢迎大家提出错误和新方案


     

    一、limit分页公式、总页数公式


    1 limit分页公式


    (1)limit分页公式:curPage是当前第几页;pageSize是一页多少条记录

    limit  (curPage-1)*pageSize,pageSize

    (2)用的地方:sql语句中

    select * from student limit(curPage-1)*pageSize,pageSize;

    2 总页数公式


    (1)总页数公式:totalRecord是总记录数;pageSize是一页分多少条记录

    int totalPageNum = (totalRecord +pageSize - 1) / pageSize;

    (2)用的地方:前台UI分页插件显示分页码
    (3)查询总条数:totalRecord是总记录数,SELECT COUNT(*) FROM tablename


    二 、Mysql的三种分页方法

     

    1 limit m,n分页语句(低效)

    select * from dept order by deptno desc limit 3,3;
    select * from dept order by deptno desc limit m,n;

    limit 3,3的意思扫描满足条件的3+3行,撇去前面的3行,返回最后的3行,那么问题来了,如果是limit 200000,200,需要扫描200200行,如果在一个高并发的应用里,每次查询需要扫描超过20W行,效率十分低下。

    测试见:https://www.cnblogs.com/youyoui/p/7851007.html

    例如:

    select * from orders_history where type=8 limit 100,100;
    select * from orders_history where type=8 limit 1000,100;
    select * from orders_history where type=8 limit 10000,100;
    select * from orders_history where type=8 limit 100000,100;
    select * from orders_history where type=8 limit 1000000,100;


    2 limit m语句 (有局限)

     select * from dept where deptno >10 order by deptno asc limit n;//下一页
     select * from dept where deptno <60 order by deptno desc limit n//上一页

    这种方式不管翻多少页只需要扫描n条数据。

    但是,虽然扫描的数据量少了,但是在某些需要跳转到多少页的时候就无法实现,这时还是需要用到方法1,既然不能避免,那么我们可以考虑尽量减小m的值,因此我们可以给这条语句加上一个条件限制。使得每次扫描不用从第一条开始。这样就能尽量减少扫描的数据量。

    例如:每页10条数据,当前是第10页,当前条目ID的最大值是109,最小值是100.(当前100-109)
    那么跳到第9页:

    select * from dept where deptno<100 order by deptno desc limit 0,10;   //倒序

    那么跳到第8页:

    select * from dept where deptno<100 order by deptno desc limit 10,10;

    那么跳到第11页:

    select * from dept where deptno>109 order by deptno asc limit 0,10;


    最后附上参考文档网址:http://www.open-open.com/doc/view/2bda32bf64864e8e965e91686f5309d4
    原文:https://blog.csdn.net/HADEWOKE/article/details/53996110

    注意:这个方法有个局限,就是需要deptno是连续的,也就是中间的记录不能有删除。(可以用删除标志代替真正的物理删除)

    上面的方法还可以优化,见第三。

    三、 查询优化

    子查询优化原理:https://zhuanlan.zhihu.com/p/163658548

    1 使用子查询优化

    这种方式先定位偏移位置的 id,然后往后查询,这种方式适用于 id 递增的情况。

    select * from orders_history where type=8 limit 100000,1;
    select id from orders_history where type=8 limit 100000,1;
    
    select * from orders_history where type=8 and 
    id>=(select id from orders_history where type=8 limit 100000,1) 
    limit 100;
    
    select * from orders_history where type=8 limit 100000,100;
    

    4条语句的查询时间如下:

    • 第1条语句:3674ms
    • 第2条语句:1315ms
    • 第3条语句:1327ms
    • 第4条语句:3710ms

    针对上面的查询需要注意:

    • 比较第1条语句和第2条语句:使用 select id 代替 select * 速度增加了3倍
    • 比较第2条语句和第3条语句:速度相差几十毫秒
    • 比较第3条语句和第4条语句:得益于 select id 速度增加,第3条语句查询速度增加了3倍

    这种方式相较于原始一般的查询方法,将会增快数倍。

     

     

    2 使用 id 限定优化(前提:id是连续递增,删除过记录不符合)

    这种方式假设数据表的id是连续递增的,则我们根据查询的页数和查询的记录数可以算出查询的id的范围,可以使用 id between and 来查询:

    select * from orders_history where type=2 
    and id between 1000000 and 1000100 limit 100;
    

    查询时间:15ms 12ms 9ms

    这种查询方式能够极大地优化查询速度,基本能够在几十毫秒之内完成。限制是只能使用于明确知道id的情况,不过一般建立表的时候,都会添加基本的id字段,这为分页查询带来很多便利。

    还可以有另外一种写法:

    select * from orders_history where id >= 1000001 limit 100;
    

    当然还可以使用 in 的方式来进行查询,这种方式经常用在多表关联的时候进行查询,使用其他表查询的id集合,来进行查询:

    select * from orders_history where id in
    (select order_id from trade_2 where goods = 'pen')
    limit 100;
    

    这种 in 查询的方式要注意:某些 mysql 版本不支持在 in 子句中使用 limit。

    3 使用临时表优化

    这种方式已经不属于查询优化,这儿附带提一下。

    对于使用 id 限定优化中的问题,需要 id 是连续递增的,但是在一些场景下,比如使用历史表的时候,或者出现过数据缺失问题时,可以考虑使用临时存储的表来记录分页的id,使用分页的id来进行 in 查询。这样能够极大的提高传统的分页查询速度,尤其是数据量上千万的时候。

     

    四、关于数据表的id说明

    一般情况下,在数据库中建立表的时候,强制为每一张表添加 id 递增字段,这样方便查询。

    如果像是订单库等数据量非常庞大,一般会进行分库分表。这个时候不建议使用数据库的 id 作为唯一标识,而应该使用分布式的高并发唯一 id 生成器来生成,并在数据表中使用另外的字段来存储这个唯一标识。

    使用先使用范围查询定位 id (或者索引),然后再使用索引进行定位数据,能够提高好几倍查询速度。即先 select id,然后再 select *;

    https://www.cnblogs.com/youyoui/p/7851007.html

    五、欢迎大家提出错误和新方案

    欢迎大家指出错误、隐患、缺陷或提出补充、更好的方案,相互探讨。

    UESTC

     

    展开全文
  • mysql 分页

    2013-04-21 22:32:36
    hibernate mysql 分页 比较乱
  • MySQL分页

    2020-05-24 14:41:05
    mysql 分页 分页查询 分页查询 MySQL 分页需要使用 limit 关键字, limit 后需要跟两个数 字, 第一个数字表示查询的起始位置, 第二个数字表示查 询的记录数. limit 要写在 order by 之后. -- 当前页数, page -- 每页...

    mysql 分页

    分页查询 分页查询
    MySQL 分页需要使用 limit 关键字, limit 后需要跟两个数
    字, 第一个数字表示查询的起始位置, 第二个数字表示查
    询的记录数. limit 要写在 order by 之后.
    -- 当前页数, page
    -- 每页显示的记录数, size
    select * from clazz limit (page-1)*size, size;
    
    展开全文
  • Mysql分页

    2019-03-14 19:47:00
    之前一直在用MsSql,最近项目开始接触MySql,不知道是数据库表...下午了解了下MySql分页(limit),感觉好方便呀 以下就是MySql分页 select * from 表limit pageSize offset (pageNumber-1)*pageSize 转载于:ht...

    之前一直在用MsSql,最近项目开始接触MySql,不知道是数据库表设计问题还是什么问题,总之查询速度特别慢

    用的orm分页查询,速度还是不行,就直接用sql了。

    下午了解了下MySql分页(limit),感觉好方便呀

    以下就是MySql分页

    select * from 表limit pageSize offset (pageNumber-1)*pageSize

     

    转载于:https://www.cnblogs.com/getmn/p/10532990.html

    展开全文
  • MySql 分页

    2016-03-06 16:56:38
    MySql 分页   由于最近项目需要,于是就简单写了个分页查询。总体而言MySql 分页机制较为简单。数据库方面只需要使用limit即可实现分页。前后台交互就直接用session传了值。 下面就写写具体的实现过程: 首先,...
    MySql 分页
    

     

    由于最近项目需要,于是就简单写了个分页查询。总体而言MySql 分页机制较为简单。数据库方面只需要使用limit即可实现分页。前后台交互就直接用session传了值。

    下面就写写具体的实现过程:

    首先,创建一个Page VO类

      其中,总记录数可由数据库查得、每页默认记录数由你自己设定;

      总页数由总记录数及每页默认记录数获取,当然得有一个条件判断;

      当前页数由当前记录数及每页默认记录数获取,当然这也得有一个条件判断;

      当前记录条数可由页面传值同时配合每页默认记录数获取。

     1 package com.ctrl.vo;
     2 
     3 public class Page {
     4     private int totalPage;// 总页数
     5     private int currentPage;// 当前页
     6     private int totalRecord;// 总记录数
     7     private int currentRecord=0;// 当前记录条数
     8     private int pageSize = 10;// 每页默认记录数
     9 
    10     public int getTotalPage() {
    11         return totalPage;
    12     }
    13 
    14     public void setTotalPage(int totalRecord, int pageSize) {
    15         if (totalRecord % pageSize == 0)
    16             this.totalPage = totalRecord / pageSize;
    17         else
    18             this.totalPage = totalRecord / pageSize + 1;
    19     }
    20 
    21     public int getCurrentPage() {
    22         return currentPage;
    23     }
    24 
    25     public void setCurrentPage(int currentRecord, int pageSize) {
    26         if (currentRecord % pageSize == 0)
    27             this.currentPage = currentRecord / pageSize;
    28         else
    29             this.currentPage = currentRecord / pageSize + 1;
    30     }
    31 
    32     public int getTotalRecord() {
    33         return totalRecord;
    34     }
    35 
    36     public void setTotalRecord(int totalRecord) {
    37         this.totalRecord = totalRecord;
    38     }
    39 
    40     public int getCurrentRecord() {
    41         return currentRecord;
    42     }
    43 
    44     public void setCurrentRecord(int currentRecord) {
    45         this.currentRecord = currentRecord;
    46     }
    47 
    48     @Override
    49     public String toString() {
    50         return "Page [totalPage=" + totalPage + ", currentPage=" + currentPage
    51                 + ", totalRecord=" + totalRecord + ", currentRecord="
    52                 + currentRecord + ", pageSize=" + pageSize + "]";
    53     }
    54 
    55     public int getPageSize() {
    56         return pageSize;
    57     }
    58 
    59     public void setPageSize(int pageSize) {
    60         this.pageSize = pageSize;
    61     }
    62     
    63 }

    其次,showUsers.jsp页面(有省略,且部分名修改)

    <c:choose>
                <c:when test="${users != null }">
                    <br>
                    <form action="#" method="post">
                        <table class="table table-striped table-bordered">
                            <thead>
                                <tr>
                                    <td>ID</td>
                                    <td>NAME</td>
                                    <td>CODE</td>
                                    <td>PWD</td>
                                    <td>STATE</td>
                                    <td>FLAG</td>
                                    <td>Update</td>
                                </tr>
                            </thead>
                            <c:forEach items="${users }" var="user">
                                <tr>
                                    <td>${user.id }</td>
                                    <td>${user.name }</td>
                                    <td>${user.code }</td>
                                    <td>${user.pwd }</td>
                                    <td>${user.state }</td>
                                    <td>${user.flag }</td>
                                    <td><a href="update.jsp?user=${user }">update</a></td>
                                </tr>
                            </c:forEach>
                        </table>
                    </form>
                    <c:if test="${flag=='T'}">
                        <a
                            href="<%=request.getContextPath()%>/showLimitUsers?currentRecord=${page.currentRecord}&type=prev">前一页</a>
                        /<a
                            href="<%=request.getContextPath()%>/showLimitUsers?currentRecord=${page.currentRecord}&type=next"> 后一页</a>
                    </c:if>
    .....

    对于,servlet后台(SERVICE、DAO层代码省略...)

            Page page = new Page();
            UserService userService = new UserServiceImpl();
            //去掉管理员
            long totalRecord = userService.getUsersCount() - 1;
            page.setTotalRecord((int) totalRecord);
            page.setTotalPage(page.getTotalRecord(), page.getPageSize());
            String type = request.getParameter("type");
            if (request.getParameter("currentRecord") != null
                    && !request.getParameter("currentRecord").equals("")) {
                int currentRecord = Integer.parseInt(request
                        .getParameter("currentRecord"));
                page.setCurrentRecord(currentRecord);
                page.setCurrentPage(page.getCurrentRecord(), page.getPageSize());
                if ("next".equals(type)
                        && page.getCurrentPage() < (page.getTotalPage() - 1)) {
                    currentRecord = currentRecord + 10;
                    page.setCurrentRecord(currentRecord);
                } else if ("prev".equals(type) && page.getCurrentPage() > 0) {
                    currentRecord = currentRecord - 10;
                    page.setCurrentRecord(currentRecord);
                }
            } else {
                page.setCurrentRecord(0);
            }
            List<User> users = userService.getLimitUsers(page.getCurrentRecord(),
                    page.getPageSize());
            page.setCurrentPage(page.getCurrentRecord(), page.getPageSize());
    
            HttpSession session = request.getSession();
            //<a>标签是否显示
            session.setAttribute("flag", "T");
            session.setAttribute("users", users);
            session.setAttribute("page", page);
    
            response.sendRedirect(request.getContextPath() + "/showUsers.jsp");

    当用户点击了next,当前记录数就加pageSize,prev则减去pageSize。同时当前页也需要与总页数之间进行比较,以防超越了页数范围。

    由于未将所有功能均设置分页,故设定flag标志,当页面其他功能不需要分页的话,可以将分页<a>消除。

     

    效果图:

    PS:文中Page VO为借鉴而来。

    心得:

      分页不难,但还是会出现bug,需要好好调试。可以通过打印Page&将所传的值在input标签显示方便调试。

    展开全文
  • MySql分页

    2021-01-12 16:15:53
    Mysql中,分页的SQL语句是: select * from table_name limit frontIndex,pageSize 这里用到了关键词limit,意思是查询表名为table_name的所有内容,从下标为frontIndex的行开始查(第一行的下标为0),查询...
  • mysql分页

    2018-03-01 16:02:56
    分页的分类:物理分页和逻辑分页物理分页:物理分页就是数据库本身提供了分页方式,如mysql的limit,好处是效率高,不好的地方就是不同数据库有不同的搞法。逻辑分页:逻辑分页利用游标分页,好处是所有数据库都统一...
  • 主要介绍了mysql分页原理和高效率的mysql分页查询语句,大家参考使用吧
  • Mysql 分页

    2017-07-14 15:46:16
    mysql> SELECT SQL_CALC_FOUND_ROWS * -> FROM tbl_name ...适用于分页场景,执行上述第一个 SQL 语句后,使用 SElECT FOUND_ROWS() 效率比 SELECT COUNT(*) 高 SELECT FOUND_ROWS() 是临时的,在
  • MYSQL 分页

    2013-08-14 08:12:02
    MYSQL 分页最简单了. SELECT  * FROM  Account  WHERE  (usertype='base' or usertype='home' or usertype='salse')   and logindate is not null order by logindate desc LIMIT 起始行, 每页多少行

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,660
精华内容 6,664
关键字:

mysql分页

mysql 订阅