2019独角兽企业重金招聘Python工程师标准>>>

很久以前的一次面试中,被面试官问到这个问题,由于平时用到的分页方法不多,只从索引、分表、使用子查询精准定位偏移以外,没有使用到其它方法。
后来在看其它博客看到了一些不同的方案,也一直没有整理。今天有时间,整理出来,分享给大家。

一,最常见MYSQL最基本的分页方式:

select * from content order by id desc limit 0, 10

在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似:

select * from content order by id desc limit 10000, 10

一言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。
此时,我们可以通过2种方式:
一,子查询的分页方式来提高分页效率,飘易用的SQL语句如下:

SELECT * FROM `content` WHERE id (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) ORDER BY id desc LIMIT $pagesize

为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。(via)通过explain SQL语句发现:子查询使用了索引!

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY content range PRIMARY PRIMARY 4 NULL 6264 Using where
2 SUBQUERY content index NULL PRIMARY 4 NULL 27085 Using index

经过飘易的实测,使用子查询的分页方式的效率比纯LIMIT提高了14-20倍!
二,JOIN分页方式

select * FROM `content` AS t1
JOIN (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) AS t2
WHERE t1.id

经过我的测试,join分页和子查询分页的效率基本在一个等级上,消耗的时间也基本一致。explain SQL语句:

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY system NULL NULL NULL NULL 1
1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 6264 Using where
2 DERIVED content index NULL PRIMARY 4 NULL 27085 Using index

三,使用MYSQL的FOUND_ROWS()函数
Mysql FOUND_ROWS() 函数结合SQL_CALC_FOUND_ROWS在SELECT中可以得到两个结果:
1. 得到Limit的内容
2. 得到去除Limit以后所有行数

SELECT语句中经常可能用LIMIT限制返回行数。有时候可能想要知道如果没有LIMIT会返回多少行,但又不想再执行一次相同语句。那么,在SELECT查询中包含SQL_CALC_FOUND_ROWS选项,然后执行FOUND_ROWS()就可以了:

select SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();

其中SQL_CALC_FOUND_ROWS 告诉Mysql将sql所处理的行数记录下来,FOUND_ROWS() 则取到了这个纪录。 虽然也是两个语句,但是只执行了一次主查询,所以效率比原来要高很多。

1. 如果在前一条语句中使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回第一条语句没有LIMIT时返回的行数。
2. 如果在前一条语句中没有使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回前一条语句实际返回的行数。
如果使用 SELECT SQL_CALC_FOUND_ROWS,MySQL必须计算所有结果集的行数。尽管这样,总比再执行一次不使用LIMIT的查询要快多了吧,因为那样结果集要返回客户端滴。(另外:应该不单是没有将结果集返回的原因,还有原因可能是比如LIKE之类比较费劲的SQL不需要再去劳累一次。)

-- 注意下面语句中的条件 LIKE
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;
SELECT FOUND_ROWS();

-- 上面语句等价于下面语句,但性能方面应该提升非常非常的明显:
SELECT COUNT(*) FROM tbl_name WHERE Name LIKE '%string%' ;
SELECT * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;

参考博客:
http://blog.hexu.org/archives/1328.shtml
http://hi.baidu.com/thinkinginlamp/blog/item/17476d22d66876a14623e81d.html
http://www.piaoyi.org/php/MySQL-SUBQUERY-index.html

转载于:https://my.oschina.net/u/998304/blog/516624

MySQL高效分页解决方案集相关推荐

  1. mysql 高效分页查询_PostgreSQL、MySQL高效分页方法探讨

    对于数据库相关的业务,逃不过的数据分页场景,无论是前台分页浏览还是划到页面底部自动加载.对于分页需求,各数据库也提供了成熟的SQL支持,类似于Hibernate等ORM框架也集成了相关的方法.但是基于 ...

  2. mysql 高效分页存储过程_mysql分页存储过程

    CREATE PROCEDURE 'sp_page'( in _pagecurrent int,--/*当前页*/ in _pagesize int,--/*每页的记录数*/ in _ifelse v ...

  3. php+mysql 大容量数据高效分页效果(弃用limit)

    发现当表中有很多上万条数据时,越后的数据用limit分页显示就越慢(>2秒),可能是mysql的特性所致.所以花了点时间总结实现了更优解决方案,最终实现毫秒级响应.若网友有更优的,请留言,谢谢! ...

  4. php mysql 高效,php+mysql 大容量数据高效分页效果(弃用limit)

    发现当表中有很多上万条数据时,越后的数据用limit分页显示就越慢(>2秒),可能是mysql的特性所致.所以花了点时间总结实现了更优解决方案,最终实现毫秒级响应.若网友有更优的,请留言,谢谢! ...

  5. 分页解决方案 —— GridView + QuickPager + QuickPager_SQL + DataAccessLibrary + 数据库

    这里要说的不仅仅是一个分页控件,而是一套解决方案,包括如何显示数据.显示分页导航,如何得到分页用的sql语句(等效于存储过程),如何提取数据,如何绑定控件,如何响应事件,添加.修改.删除数据后如何更新 ...

  6. Mysql高并发解决方案

    Mysql高并发解决方案 前言 随着近些年来分布式的应用,其伴随而来的是系统的数据量也越来越大,为了可以提升系统的整体性能,我们对以Mysql为代表的关系型数据库也提出了"分布式" ...

  7. sqlanyshere转mysql_【SQL】Oracle和Mysql的分页、重复数据查询(limit、rownum、rowid)

    上周三面试题有两道涉及Oracle的分页查询,没有意外地凉了,现在总结一下. · Mysql mysql的分页可以直接使用关键字limit,句子写起来比较方便. 语法: ① limit m,n -- ...

  8. mysql核心数据库_从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程...

    从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程 课程目录 (1) 01MySQL基础_课程引入.avi (2) 02MySQL基础_为什么学习 ...

  9. mysql高可靠部署_可能是我见过最好的 MySQL 高可用解决方案 MySQL InnoDB Cluster 中文教程!...

    公众号关注 「运维之美」设为「星标」,每天带你玩转 Linux ! 这篇文章将详细地介绍 MySQL 的高可用解决方案-- MySQL InnoDB Cluster. 说到高可用性,首先要了解一下什么 ...

最新文章

  1. 强化学习:如何处理大规模离散动作空间
  2. 第2条 遇到多个构造器参数时要考虑构建器
  3. 洛谷P1402 酒店之王(二分图)
  4. 微信小程序接入腾讯地图sdk地图 用户自选位置。踩坑+代码实现
  5. 【可运行,刘汝佳代码】Trees on the level UVA - 122
  6. MySQL 覆盖索引、最左前缀原则、索引下推
  7. servlet 异常处理_Servlet异常和错误处理示例教程
  8. 编程基本功训练:流程图画法及练�
  9. oracle数据库ora01012错误,Oracle自定义异常收集(二)
  10. 小米手机助手 云服务器错误,小米手机助手连接手机失败的处理操作过程
  11. XDG0062 XAML 与XDG0008 XAML 错误的解决办法
  12. 无锡江苏高性能服务器服务商,无锡高防云服务器
  13. 数显之家快讯:【SHIO世硕心语】做为职业经理人,你想成为车轮,还是发动机,还是方向盘?
  14. 1-(2-甲氧基乙基)-3-乙基咪唑三氟甲基磺酸盐{[C22O1IM][TfO]}离子液体
  15. 运营版uniapp多商户商城小程序+H5+APP+商家入驻短视频社区种草直播阶梯拼团
  16. php汉字全是问号_PHP-PHP中文显示问号问题
  17. 有趣的排序算法——Monkey King排序 详细介绍
  18. 【STM32+cubemx】0026 HAL库开发:NRF24L01无线2.4G通信模块的应用
  19. loam源码解析5 : laserOdometry(三)
  20. 安居客冲刺上市:姚劲波全力支持,距离贝壳找房还差6个我爱我家

热门文章

  1. 错误代码为0xC000218,0x00000051的蓝屏错误,或是提示 System32/config missing之类的注册表错误...
  2. 【玩转.Net MF – 03】远程文件查看器
  3. linux文件I/O操作
  4. Golang —— goroutine(协程)和channel(管道)
  5. [ZJOI2011]细胞——斐波那契数列+矩阵加速+dp
  6. 如何减少浏览器repaint和reflow(下)
  7. 查看binlog文件的2种方式
  8. 北京驾照到期换证简记
  9. Emm,qW3xT.2(矿机进程)
  10. Xamarin.Android 调用本地相册