有朋友问: MySQL的分页似乎一直是个问题,有什么优化方法吗?网上看到网上推荐了一些分页方法,但似乎不太可行,你能点评一下吗?

  方法1: 直接使用数据库提供的SQL语句

  ---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N。

  ---适应场景: 适用于数据量较少的情况(元组百/千级)。

  ---原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3)。Limit限制的是从结果集的M位置处取出N条输出,其余抛弃。

  方法2: 建立主键或唯一索引, 利用索引(假设每页10条)

  ---语句样式: MySQL中,可用如下方法:

  SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) LIMIT M。

  ---适应场景: 适用于数据量多的情况(元组数上万)。

  ---原因: 索引扫描,速度会很快。有朋友提出因为数据查询出来并不是按照pk_id排序的,所以会有漏掉数据的情况,只能方法3。

  方法3: 基于索引再排序

  ---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M。

  ---适应场景: 适用于数据量多的情况(元组数上万). 最好ORDER  BY后的列对象是主键或唯一所以,使得ORDERBY操作能利用索引被消除但结果集是稳定的(稳定的含义,参见方法1)。

  ---原因: 索引扫描,速度会很快. 但MySQL的排序操作,只有ASC没有DESC(DESC是假的,未来会做真正的DESC,期待)。

  方法4: 基于索引使用prepare(第一个问号表示pageNum,第二个?表示每页元组数)

  ---语句样式: MySQL中,可用如下方法:

  PREPARE stmt_name FROM SELECT * FROM 表名称 WHERE id_pk > (?* ?) ORDER BY id_pk

  ASC LIMIT M。

  ---适应场景: 大数据量。

  ---原因: 索引扫描,速度会很快. prepare语句又比一般的查询语句快一点。

  方法5:利用MySQL支持ORDER操作可以利用索引快速定位部分元组,避免全表扫描

  ---比如: 读第1000到1019行元组(pk是主键/唯一键)。

  ---SELECT * FROM your_table WHERE pk>=1000 ORDER BY pk ASC LIMIT 0,20。

  方法6: 利用"子查询/连接+索引"快速定位元组的位置,然后再读取元组. 道理同方法5

  ---如(id是主键/唯一键,蓝色字体时变量):

  利用子查询示例:

1
2
3
4
SELECT * FROM your_table WHERE id <=
(SELECT id FROM your_table ORDER
BY id desc LIMIT ($page-1)*$pagesize ORDER BY id desc
LIMIT $pagesize

  利用连接示例:

1
2
3
4
5
SELECT * FROM your_table AS t1
JOIN (SELECT id FROM your_table ORDER BY
id desc LIMIT ($page-1)*$pagesize AS t2
WHERE
t1.id <= t2.id ORDER BY t1.id desc LIMIT $pagesize;

  方法7: 存储过程类(最好融合上述方法5/6)

  ---语句样式: 不再给出

  ---适应场景: 大数据量.  作者推荐的方法

  ---原因: 把操作封装在服务器,相对更快一些。

  方法8: 反面方法

  ---网上有人写使用 SQL_CALC_FOUND_ROWS。 没有道理,勿模仿 。

  基本上,可以推广到所有数据库,道理是一样的。但方法5未必能推广到其他数据库,推广的前提是,其他数据库支持ORDER BY操作可以利用索引直接完成排序。

MySQL的分页的更多相关文章

  1. MySQL的分页优化

    今天下午,帮同事重写了一个MySQL SQL语句,该SQL语句涉及两张表,其中一张表是字典表(需返回一个字段),另一张表是业务表(本身就有150个字段,需全部返回),当然,字段的个数是否合理在这里不予 ...

  2. oracle sqlserver mysql数据库分页

    1.Mysql的limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. SELECT * FROM tabl ...

  3. MySql通用分页存储过程

    MySql通用分页存储过程 1MySql通用分页存储过程 2 3过程参数 4p_cloumns varchar(500),p_tables varchar(100),p_where varchar(4 ...

  4. Statement和PreparedStatement的特点 MySQL数据库分页 存取大对象 批处理 获取数据库主键值

    1 Statement和PreparedStatement的特点   a)对于创建和删除表或数据库,我们可以使用executeUpdate(),该方法返回0,表示未影向表中任何记录   b)对于创建和 ...

  5. mysql 查询优化~ 分页优化讲解

    一 简介:今天咱们来聊聊mysql的分页查询二 语法     LIMIT [offset,] rows     offset是第多少条     rows代表多少条之后的行数    性能消耗    se ...

  6. mysql实现分页的几种方式

    mysql实现分页的几种方式: 第一种:使用框架自带的pageable来进行分页 package com.cellstrain.icell.repository.repositoryImpl; imp ...

  7. mybatis对mysql进行分页

    Mybatis对mysql数据库分页 在generator中增加插件,下载地址http://download.csdn.net/detail/shunlongjin/6937045 <plugi ...

  8. atitit。mssql sql server 转换mysql 及 分页sql ast的搭建

    atitit.mssql sql server 转换mysql  及 分页sql ast的搭建 1. 主要的的转换::函数的转换,分页的转换 1 2. 思路::mssql sql >>as ...

  9. oracle 的分页与 mySQL'的分页转化

    oracle 分页:  关键字ROWNUM SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO FROM ( SELECT A.*, ...

随机推荐

  1. [vijos1892]树上的最大匹配(树形DP)

    题目:https://vijos.org/p/1892 分析:(100分其实用到各种c++优化,没什么实际意义,所以弄70就可以了) 题目很简单,很容易想出用树形DP,但是求方案数的时候,满满都是细节 ...

  2. Grunt-cli的执行过程以及Grunt加载原理

    通过本篇你可以了解到: 1 grunt-cli的执行原理 2 nodeJS中模块的加载过程 Grunt-cli原理 grunt-cli其实也是Node模块,它可以帮助我们在控制台中直接运行grunt命 ...

  3. linux 添加永久ip、路由和开启路由功能

    一.添加永久ip 编辑/etc/sysconfig/network-scripts/ifcfg-eth0文件: 网络接口配置文件 [root@localhost ~]# cat /etc/syscon ...

  4. new-nav-css

    header:before, header:after ,.navigation:before, .navigation:after,.nav-row:before, .nav-row:after,. ...

  5. hdu4333 扩展KMP

    慢慢研究可以发现,可以用扩展kmp来求.由于扩展kmp的next[]只有一部分,当前位子前面那部分和母串的后部分,所以可以将字符串复制接在后面一次. 先求如果next[]>0&& ...

  6. MyEclipse 开发 Web项目发布到 Tomcat 下的Root 目录

    通常情况下,Web项目是发布到Tomcat下的webapps文件目录下的 . 例如:Web应用项目名称为:stock,则部署到tomcat后,是部署在tomcat/webapps/stock中,网址为 ...

  7. Java-优化技术

    常用的: 1.优化循环.通过重新组织重复的子表达式来提高循环体的运行性能. 2减少使用对象的数量来提高运行性能. 3.缩减网络传输数据来缩短等待时间. 其他: 1.采用对象池技术,提高对象的利用效率. ...

  8. Statement,PreparedStatement和CallableStatement的联系和区别

    联系: CallableStatement继承自PreparedSatement,PreparedStatement继承自Statement. 区别: 1:Statement 每次执行sql语句,数据 ...

  9. Netbeans 中的编译器相关配置

    gcc-core:C 编译器 gcc-g++:C++ 编译器 gdb:GNU 调试器 make:"make" 实用程序的 GNU 版本

  10. css常用技巧

    去点号 list-style:none; 字体居中 text-align:center; 链接去下划线 text-decoration:none; 鼠标禁止右键 <body oncontextm ...