(转)Mysql LIMIT如何正确对其进行优化
以下的文章主要是对Mysql LIMIT简单介绍,我们大家都知道LIMIT子句一般是用来限制SELECT语句返回的实际行数。LIMIT取1个或是2个数字参数,如果给定的是2个参数,第一个指定要返回的第一行的偏移量,第二个指定返回行的最大数目。
初始行的偏移量是0(不是1)。
mysql> select * from table LIMIT 6,10;
得到第7-16行
如果给定一个参数,它指出返回行的最大数目。
mysql> select * from table LIMIT 5;
得到前5行
换句话说,LIMIT n等价于Mysql LIMIT 0,n。MYSQL的优化是非常重要的。其他最常用也最需要优化的就是limit。mysql的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。同样是取10条数据
select * from yanxue8_visit limit 10000,10
和
select * from yanxue8_visit limit 0,10
就不是一个数量级别的。
网上也很多关于limit的五条优化准则,都是翻译自mysql手册,虽然正确但不实用。今天发现一篇文章写了些关于limit优化的,很不错。原文地址:http://www.zhenhua.org/article.asp?id=200(下面附有原文)
文中不是直接使用limit,而是首先获取到offset的id然后直接使用Mysql limit size来获取数据。根据他的数据,明显要好于直接使用limit。这里我具体使用数据分两种情况进行测试。(测试环境win2033+p4双核(3GHZ) +4G内存 mysql 5.0.19)
1、offset比较小的时候。
select * from yanxue8_visit limit 10,10
多次运行,时间保持在0.0004-0.0005之间
Select * From yanxue8_visit Where vid >=(
Select vid From yanxue8_visit Order By vid limit 10,1
) limit 10
多次运行,时间保持在0.0005-0.0006之间,主要是0.0006结论:偏移offset较小的时候,直接使用limit较优。这个显然是子查询的原因。
2、offset大的时候
select * from yanxue8_visit limit 10000,10
多次运行,时间保持在0.0187左右
Select * From yanxue8_visit Where vid >=(
Select vid From yanxue8_visit Order By vid limit 10000,1
) limit 10
多次运行,时间保持在0.0061左右,只有前者的1/3。可以预计offset越大,后者越优。
附上原文:
select * from table LIMIT 5,10; #返回第6-15行数据
select * from table LIMIT 5; #返回前5行
select * from table LIMIT 0,5; #返回前5行
性能优化:
基于MySQL5.0中Mysql limit的高性能,我对数据分页也重新有了新的认识.
Select * From cyclopedia Where ID>=(
Select Max(ID) From (
Select ID From cyclopedia Order By ID limit 90001
) As tmp
) limit 100;
Select * From cyclopedia Where ID>=(
Select Max(ID) From (
Select ID From cyclopedia Order By ID limit 90000,1
) As tmp
) limit 100;
同样是取90000条后100条记录,第1句快还是第2句快?
第1句是先取了前90001条记录,取其中最大一个ID值作为起始标识,然后利用它可以快速定位下100条记录
第2句择是仅仅取90000条记录后1条,然后取ID值作起始标识定位下100条记录
第1句执行结果.100 rows in set (0.23) sec
第2句执行结果.100 rows in set (0.19) sec
很明显第2句胜出.看来limit好像并不完全像我之前想象的那样做全表扫描返回limit offset+length条记录,这样看来limit比起MS-SQL的Top性能还是要提高不少的.
其实第2句完全可以简化成
Select * From cyclopedia Where ID>=(
Select ID From cyclopedia limit 90000,1
)limit 100;
直接利用第90000条记录的ID,不用经过Max运算,这样做理论上效率因该高一些,但在实际使用中几乎看不到效果,因为本身定位ID返回的就是1条记录,Max几乎不用运作就能得到结果,但这样写更清淅明朗,省去了画蛇那一足.
可是,既然MySQL有limit可以直接控制取出记录的位置,为什么不干脆用Select * From cyclopedia limit 90000,1呢?岂不更简洁?
这样想就错了,试了就知道,结果是:1 row in set (8.88) sec,怎么样,够吓人的吧,让我想起了昨天在4.1中比这还有过之的"高分".Select * 最好不要随便用,要本着用什么,选什么的原则, Select的字段越多,字段数据量越大,速度就越慢. 上面2种分页方式哪种都比单写这1句强多了,虽然看起来好像查询的次数更多一些,但实际上是以较小的代价换取了高效的性能,是非常值得的.
第1种方案同样可用于MS-SQL,而且可能是最好的.因为靠主键ID来定位起始段总是最快的.
Select Top 100 * From cyclopedia Where ID>=(
Select Top 90001 Max(ID) From (
Select ID From cyclopedia Order By ID
) As tmp
)
但不管是实现方式是存贮过程还是直接代码中,瓶颈始终在于MS-SQL的TOP总是要返回前N个记录,这种情况在数据量不大时感受不深,但如果成百上千万,效率肯定会低下的.相比之下MySQL的Mysql limit就有优势的多,执行:
Select ID From cyclopedia limit 90000
Select ID From cyclopedia limit 90000,1
而MS-SQL只能用Select Top 90000 ID From cyclopedia 执行时间是390ms,执行同样的操作时间也不及MySQL的360ms.
【编辑推荐】
- Mysql安装与qmail实际操作概述
- 建立MySQL镜像数据库在linux下的简单方案
- MySQL 数据库的双机热备实际操作配置
- MySQL 安装备份在Linux系统中的安装
- 解决MySQL中文乱码的方法归纳
转自:http://database.51cto.com/art/201005/200395.htm
(转)Mysql LIMIT如何正确对其进行优化的更多相关文章
- Mysql LIMIT如何正确对其进行优化
Mysql LIMIT如何正确对其进行优化 2010-05-17 17:09 佚名 博客园 字号:T | T 我们今天主要和大家分享的是Mysql LIMIT简单介绍以及如何进行优化的相关内容的描述, ...
- 大数据量时 Mysql LIMIT如何正确对其进行优化(转载)
以下的文章主要是对Mysql LIMIT简单介绍,我们大家都知道LIMIT子句一般是用来限制SELECT语句返回的实际行数.LIMIT取1个或是2个数字参数,如果给定的是2个参数,第一个指定要返回的第 ...
- MySQL limit 分页查询优化(百万级优化)
1)简单的查询分页:分每页5条 limit [offset],[rows] ,10; 2)建立id索引:查询索引id ,) limit ; 3)使用 between and 语句分页效率快N倍 ; 4 ...
- MySQL触发器如何正确使用
MySQL触发器如何正确使用 2010-05-18 15:58 佚名 博客园 字号:T | T 我们今天主要向大家介绍的是MySQL触发器进行正确使用,其中包括对MySQL触发器发器的语句创建,触发时 ...
- mysql limit查询优化
mysql数据库中的查询语句有关limit语句的优化. 一般limit是用在分页的程序的分页上的,当应用数据量够小时,也许感觉不到limit语句的任何问题,但当查询数据量达到一定程度时,limit的性 ...
- Mysql limit offset
Mysql limit offset 假设数据库表student存在13条数据. 语句1:select * from student limit 9,4 语句2:slect * from studen ...
- 如何优化Mysql千万级快速分页,limit优化快速分页,MySQL处理千万级数据查询的优化方案
如何优化Mysql千万级快速分页,limit优化快速分页,MySQL处理千万级数据查询的优化方案
- mysql limit语句
[mysql limit语句] 代码: SELECT * FROM table LIMIT 2 OFFSET 1; 比如这个SQL ,limit后面跟的是2条数据,offset后面是从第1条开始读取. ...
- Mysql limit offset用法举例
转自:http://blog.csdn.net/iastro/article/details/53037600 Mysql limit offset示例 例1,假设数据库表student存在13条数据 ...
随机推荐
- excel 导入mysql
1. excel 导出csv格式,很简单导出即可 2. 使用命令行,进入mysql之后,使用命令行 tips: 删除第一行的属性名,csv后面若有空数据也可以删除,当然你不删除也没有关系,可以在mys ...
- Linux用户及文件权限管理
Linux用户及文件权限管理
- python如何去掉字符串‘\xa0’
发现问题: 最近在用爬虫爬取网页信息时,在网页源码中遇到了“ "字符串,经查阅,发现该字符是不间断空格符.我们通常所用的空格是 \x20 ,是在标准ASCII可见字符 0x2 ...
- ThinkPHP框架 祖辈分的理解 【儿子 FenyeController】继承了【父亲 FuController】继承了【祖辈 Controller】的
注:系统自带的Controller方法代表的是祖辈 FuController控制器是自定义的,代表父亲... FenyeController控制器就代表着儿子 [儿子 FenyeController] ...
- WordPlayer
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- 洛谷P1032 字串变换【bfs】
题目链接:https://www.luogu.org/problemnew/show/P1032 题意: 给定一个原字符串和目标字符串,以及几个字符串变换的规则. 问能否根据这几个规则在十步之内把原字 ...
- [No0000B3].NET C# 单体模式(Singleton)
单体模式(Singleton)是经常为了保证应用程序操作某一全局对象,让其保持一致而产生的对象,例如对文件的读写操作的锁定,数据库操作的时候的事务回滚,还有任务管理器操作,都是一单体模式读取的.创建一 ...
- PCIe 复位:Clod reset、warm reset、Hot reset、Function level reset
2015年09月06日 17:06:01 yijingjing17 阅读数:9029 标签: PCIEReSet复位Clod resetwarm reset 更多 个人分类: PCIe ...
- [daily][archlinux][rsync] rsync
科普文档:https://wiki.archlinux.org/index.php/Rsync 之前改文件系统时,用过. 然而用的不太对,导致一部分文件的权限出了问题. [troubleshoot][ ...
- ORACLE监听配置及测试实验(2)
实验四 在tnsname.ora里添加默认监听代号 [oracle@oracle01 admin]$ vi tnsnames.ora 添加一行 PORT1528=(ADDRESS = (PROTOCO ...