有朋友问: 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. 使用Git进行代码管理

    Git简介 Git 是 Linux Torvalds 为了帮助管理 Linux® 内核开发而开发的一个开放源码的版本控制软件. 先讲一下如何把开源项目fork到自己的github中 1.  点击图中的 ...

  2. VS中两个常用辅助工具

    一. 首当推荐的是DPack 下载地址:http://www.usysware.com/dpack/ 快捷键:以下都是个人常用的热键.其他还有,我都用得比较少了,3个已经完全够了 Alt+U   查找 ...

  3. Java基础-常量

    常量是一种标识符,它的值在运行期间恒定不变.并且常量在程序中只能被引用,而不能被重新赋值. 以下,我们在Math类中就定义了一个全局常量PI被final关键字修饰的变量名最好要大写. public c ...

  4. Yii2登陆添加验证码

    models中 LoginForm.php public $verifyCode; public function rules() { return [ …… ['verifyCode', 'capt ...

  5. BZOJ-1015 StarWar星球大战 并查集+离线处理

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec Memory Limit: 162 MB Submit: 4105 Solved: 1826 [Submit ...

  6. Ecshop /admin/get_password.php Password Recovery Secrect Code Which Can Predict Vulnerability

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Ecshop提供了密码找回功能,但是整个密码找回流程中存在一些设计上的安全隐患 . ...

  7. java 中LinkedList的学习

    Java中,所有链表实际上都是双向链表的,即每个结点还存放在着指向前驱结点的引用. LinkedList中的contains方法检测某个元素是否出现在链表中. LinkedList类提供了一个用来访问 ...

  8. groovy-语句

    groovy语句类似于java语句,但是在groovy中的分号”;”是可选的.比如: 1 def x = [1, 2, 3] 2 println x 3 def y = 5; def x = y +  ...

  9. 【Beta阶段】发布说明

    在经历Beta阶段紧张的开发后,本次Beta阶段取得的成果虽然不如Alpha阶段多,但是也算是做到了稳中求进,一共预想了三个feature,最终做出了预想的两个feature. 新功能说明 新的主页: ...

  10. iOS应用支持IPV6

    一.IPV6-Only支持是啥? 首先IPV6,是对IPV4地址空间的扩充.目前当我们用iOS设备连接上Wifi.4G.3G等网络时,设备被分配的地址均是IPV4地址,但是随着运营商和企业逐渐部署IP ...