mysql-分页查询方案
一.直接使用limit最简单查询方法:
select * from content order by id desc limit 0, 10
在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。
随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似:
select * from content order by id desc limit 10000, 10
言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。
此时,通过2中方式:
二.子查询分页方式来提高效率
SELECT * FROM `content` WHERE id <=
(SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) ORDER BY id desc LIMIT $pagesize
如
SELECT * FROM `log_data` WHERE id <=
(SELECT id FROM `log_data` ORDER BY id desc LIMIT 5, 1) ORDER BY id desc LIMIT 5
为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。
(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
三.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 <= t2.id ORDER BY t1.id desc LIMIT $pagesize;
如
SELECT * FROM `log_data` AS t1
JOIN (SELECT id FROM `log_data` ORDER BY id desc LIMIT 5, 1) AS t2
WHERE t1.id <= t2.id ORDER BY t1.id desc LIMIT 5;
经过测试,join分页和子查询分页的效率基本在一个等级上,消耗的时间也基本一致。explain SQL语句:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> 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;
五.使用存储过程
DELIMITER $$;
DROP PROCEDURE IF EXISTS `sp_page`$$
CREATE PROCEDURE `sp_page`(
in _pagecurrent int,/*当前页*/
in _pagesize int,/*每页的记录数*/
in _ifelse varchar(1000),/*显示字段*/
in _where varchar(1000),/*条件*/
in _order varchar(1000)/*排序*/
)
COMMENT '分页存储过程'
BEGIN
if _pagesize<=1 then
set _pagesize=20;
end if;
if _pagecurrent < 1 then
set _pagecurrent = 1;
end if; set @strsql = concat('select ',_ifelse,' from ',_where,' ',_order,' limit ',_pagecurrent*_pagesize-_pagesize,',',_pagesize);
prepare stmtsql from @strsql;
execute stmtsql;
deallocate prepare stmtsql;
set @strsqlcount=concat('select count(1) as count from ',_where);/*count(1) 这个字段最好是主键*/
prepare stmtsqlcount from @strsqlcount;
execute stmtsqlcount;
deallocate prepare stmtsqlcount;
END$$
DELIMITER ;$$
调用代码
调用例1 call sp_Page(1,3,'*','test','order by id desc'); 调用例2 call sp_Page(1,3,'*','test where sort=1','order by id desc'); 调用例3 call sp_Page(1,3,'id,title','test where sort=1','order by id desc');
mysql-分页查询方案的更多相关文章
- 复盘MySQL分页查询优化方案
一.前言 MySQL分页查询作为Java面试的一道高频面试题,这里有必要实践一下,毕竟实践出真知. 很多同学在做测试时苦于没有海量数据,官方其实是有一套测试库的. 二.模拟数据 这里模拟数据分2种情况 ...
- 使用聚集索引和非聚集索引对MySQL分页查询的优化
内容摘录来源:MSSQL123 ,lujun9972.github.io/blog/2018/03/13/如何编写bash-completion-script/ 一.先公布下结论: 1.如果分页排序字 ...
- mysql 分页查询
mysql,; : mysql,; -last. //如果只给定一个参数,它表示返回最大的记录行数目: mysql; 个记录行 ,n. 动态传参的分页查询 SELECT * FROM table LI ...
- mysql分页查询详解
我们做的后端项目一般都会有admin管理端,当管理端将要展示数据的时候,就需要用到分页.所以分页的考查在面试中也相当多.在mysql中进行分页查询时,一般会使用limit查询,而且通常查询中都会使用o ...
- Java GUI+mysql+分页查询
1.要求 : 创建一个学生信息管理数据库 2.实现分页查询 代码如下: a)学生实体类: /** * @author: Annie * @date:2016年6月23日 * @description: ...
- Mysql分页查询性能分析
[PS:原文手打,转载说明出处,博客园] 前言 看过一堆的百度,最终还是自己做了一次实验,本文基于Mysql5.7.17版本,Mysql引擎为InnoDB,编码为utf8,排序规则为utf8_gene ...
- MySql分页查询慢|这里告诉你答案
一.背景 我们在开发的过程中使用分页是不可避免的,通常情况下我们的做法是使用limit加偏移量:select * from table where column=xxx order by xxx li ...
- MySQL分页查询性能优化
当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方 ...
- MySQL分页查询大数据量优化方法
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...
- mysql分页查询语法
一.limit语法 SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指 ...
随机推荐
- [3D跑酷] MissionManager
前言 许久没有更新日志了,之前写了GUIManager,GUIClickEventReceiver还有AudioManager,这次写MissionManager 引用关系 首先看下MissionMa ...
- Facebook或成云领域黑马 冲击亚马逊
[摘要]目前,云计算领域最大的服务是亚马逊AWS,据称此服务年度营收约为100亿美元. 转播到腾讯微博 BI中文站 3月22日报道 如今,多数人认为亚马逊在云计算领域的发展势头无人可档,不过,这个市场 ...
- C和指针笔记 3.6链接属性
链接属性决定如何处理在不同文件中出现的标识符.标识符的作用域也它的链接属性有关,但这两个属性并不相同. 没有链接属性的标识符(none)总是被当作单独的个体,也就是说该标识符的多个声明被当作独立不同的 ...
- C++容器的复制
C++容器的复制不同于Java Java是引用复制,复制的仅仅是对象的引用, 在需要复制容器内对象的副本集合的情况,需要使用Clone方法,而且要注意clone方法的浅拷贝 深拷贝 C++的容器复制 ...
- Linux下检测IP地址冲突及解决方法
问题说明:在公司办公网内的一台物理机A上安装了linux系统(ip:192.168.9.120),在上面部署了jenkins,redmine,svn程序.由于是在办公网内,这台机器和同事电脑都是在同一 ...
- linux下安装php的imagick扩展模块(附php升级脚本)
imagick是一个PHP的扩展,是一套软件系列,用ImageMagick提供的API来进行图片的创建与修改,不过这些操作已经包装到扩展imagick中去了,最终调用的是ImageMagick提供的A ...
- Linux Linux程序练习十二(select实现QQ群聊)
//头文件--helper.h #ifndef _vzhang #define _vzhang #ifdef __cplusplus extern "C" { #endif #de ...
- C++ 栈的基本操作
// zhan.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using namesp ...
- 可以ping通的打印机,没有办法打印
可以ping通打印机的电脑,但是访问不了打印机的共享设置.\\XXX.XXX.XXX.XXX 之后出现如下错误: 您可能没有权限使用网络资源.请与这台服务器的管理员联系以查明您是否有访问权限.目前没 ...
- Objective-c基础学习
核心内容 标识号 OC语言中,对各种变量,方法和类等要素命名时使用的字符序列称为标识符. OC标识符命名规则标识符由字母,下划线“_”,美元符号“$”和数字组成,标识符必须以字母,下划线,美元符号开头 ...