[MySQL性能优化系列]LIMIT语句优化
1. 背景
假设有如下SQL语句:
SELECT * FROM table1 LIMIT offset, rows
这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处理能力有限,希望每次只取一部分结果进行处理。
上述SQL语句的实现机制是:
- 从“table”表中读取offset+rows行记录
- 抛弃前面的offset行记录,返回后面的rows行记录作为最终结果。
这种实现机制存在一个弊端:虽然只需要返回rows行记录,但却必须先访问offset行不会用到的记录。对一张数据量很大的表进行查询时,offset值可能非常大,此时limit语句的效率就非常低了。
2. 简单查询的LIMIT优化
假设表message表中有10万行记录,每次取1000条。
优化前:
SELECT message.* FROM message LIMIT 0,1000
SELECT message.* FROM message LIMIT 1000,1000
SELECT message.* FROM message LIMIT 2000,1000
……
SELECT message.* FROM message LIMIT 998000,1000
SELECT message.* FROM message LIMIT 999000,1000
优化后(利用自增主键,避免offset的使用):
SELECT message.* FROM message WHERE uid>0 LIMIT 1000
SELECT message.* FROM message WHERE uid>1000 LIMIT 1000
SELECT message.* FROM message WHERE uid>2000 LIMIT 1000
……
SELECT message.* FROM message WHERE uid>998000 LIMIT 1000
SELECT message.* FROM message WHERE uid>999000 LIMIT 1000
在笔者的机器上,优化前,SQL语句从前往后越来越慢(最后一条语句执行了150毫秒),而优化后,每条语句的耗时都是微妙级的。
3. 复杂查询的LIMIT优化
实际工程中遇到的查询,通常要复杂些,比如,多表查询、条件查询。这种情况下,查询结果通常不是按照自增主键的顺序逐一排列的。
例如,对于下述SQL语句,就不能像第二节那样优化了:
SELECT timerec FROM message WHERE evttype = 1 AND nodename = 'node1'
LIMIT 0,1000
……
SELECT timerec FROM message WHERE evttype = 1 AND nodename = 'node1'
LIMIT 999000,1000
……
优化方案:建立临时表(含自增主键)存储数十万行的查询结果,之后用第二节的方法分多次访问临时表、获取数据。
- 创建临时表
CREATE TEMPORARY TABLE tmp_timerec(
`uid` bigint(20) NOT NULL AUTO_INCREMENT,
`timerec` datetime NOT NULL,
PRIMARY KEY (`uid`))
- 插入查询结果到临时表
INSERT INTO tmp_timerec
SELECT null,timerec FROM message
WHERE evttype = 1 AND nodename = ‘node1’
- 分多次查询临时表
SELECT timerec FROM tmp_timerec where uid > 0 LIMIT 1000
……
SELECT timerec FROM tmp_timerec where uid > 999000 LIMIT 1000
最后,附上MySQL性能优化系列的全部链接:
- [MySQL性能优化系列]巧用索引 http://www.cnblogs.com/beynol/p/mysql-optimization-index.html
- [MySQL性能优化系列]LIMIT语句优化 http://www.cnblogs.com/beynol/p/mysql-optimization-limit.html
- [MySQL性能优化系列]提高缓存命中率 http://www.cnblogs.com/beynol/p/mysql-optimization-cache.html
[MySQL性能优化系列]LIMIT语句优化的更多相关文章
- 浅谈mysql配置优化和sql语句优化【转】
做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...
- 数据库的优化(表优化和sql语句优化)
在这里主要是分为表设计优化和sql语句优化两方面来实现. 首先的是表设计优化: 1.数据行的长度不要超过8020字节.如果是超过这个长度的话这条数据会占用两行,减低查询的效率. 2.能用数字类型就不要 ...
- mysql优化和sql语句优化总结
mysql性能优化 1. EXPLAIN 你的 SELECT 查询.使用 EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的.这可以帮你分析你的查询语句或是表结构的性能瓶颈. 2. ...
- mysql优化之SQL语句优化
Mysql优化是一个老生常谈的问题, 优化的方向也优化很多:从架构层;从设计层;从存储层;从SQL语句层; 今天讲解一下从SQL语句层: 这个部分是程序员最容易把控的地方,也是最容易忽视的地方. 一个 ...
- MySql(八):MySQL性能调优——Query 的优化
一.理解MySQL的Query Optimizer MySQL Optimizer是一个专门负责优化SELECT 语句的优化器模块,它主要的功能就是通过计算分析系统中收集的各种统计信息,为客户端请求的 ...
- 数据库性能调优——sql语句优化(转载及整理) —— 篇1
一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实 ...
- 数据库性能优化之SQL语句优化
一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写等是体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统 ...
- ORACLE性能优化之SQL语句优化
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 操作环境:AIX +11g+PLSQL 包含以下内容: 1. SQL语句执行过程 2. 优化器及执行计划 3. 合 ...
- 数据库性能优化之SQL语句优化(上)
一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的 ...
随机推荐
- 相克军_Oracle体系_随堂笔记008-存储结构
控制文件.数据文件.日志文件 放在存储上. 参数文件:数据库启动时读取,并不关闭,但是启动过后丢了也没事.一般放在服务器上. $ORACLE_HOME/dbs下 备份文件{ 控制 ...
- 基本的window.document操作及实例
基本的window.document操作及实例 找元素 1.根据id找 var d1 = document.getElementById("d1"); alert(d1); 2.根 ...
- Java继承与组合
Java继承与组合 继承 java 中使用extends关键字表示继承关系,当创建一个类时,如果没有明确指出要继承的类,则是隐式地从根类Object进行继承. 子类继承父类的成员变量 子类能够继承父类 ...
- JavaScript的三种工业化调试方法
JavaScript的三种工业化玩法 软件工程中任何的语言如果想要写出健壮的代码都需要锋利的工具,当然JavaScript也不例外,很多朋友刚入门的时候往往因为工具选的不对而事半功倍,JavaScri ...
- [Web API] Web API 2 深入系列(2) 消息管道
目录 HttpMessageHandler Web Host模式处理过程 Self Host模式处理过程 HttpMessageHandler Web API处理管道由一系列HttpMessageHa ...
- 记一SQL部署问题
在部署环境时,不同的环境可能会有一些不同步,而个人遇到的问题就是在开发环境中表中均有字段 BestCaseId 和 RiskId 字段,生产环境中目前只有 BestCaseId 字段,新搭建的测试环境 ...
- 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间
[源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...
- 简谈asp.net下的异步加载
具体我本身大概用的就有两种,需配合JQ. 第一种,直接通过AJAX去请求页面:例如, 1:dataType必须是html或者Text格式, 2:Type:必须是'Post'请求 3:后台Load事件必 ...
- SQL SERVER2012附加 (PS:开始试过sql2012直接附加失败)
Northwind 示例数据库下载: NORTHWND.MDF (PS:开始试过sql2012直接附加失败) 新建查询-执行下面代码 USE [master] GO CREATE DATABAS ...
- IDE有毒
程序员按项目性质大致有三种:写Demo的.写Proto的.写成品的:按项目开发周期大致有:写开头的.写中间的.写结尾的. Demo是样品,主要是表面上初步实现,临时忽悠客户用的,不一定要求继续演化: ...