优化mysql的limit offset的例子

经常碰到的一个问题是limit的offset太高,如:limit 100000,20,这样系统会查询100020条,然后把前面的100000条都扔掉,这是开销很大的操作,导致查询很慢。假设所有分页的页面访问频率一样,这样的查询平均扫描表的一半数据。优化的方法,要么限制访问后面的页数,要么提升高偏移的查询效率。

一个简单的优化办法是使用覆盖查询(covering index)查询,然后再跟全行的做join操作。如:

代码如下:

SQL>select * from user_order_info limit 1000000,5;

这条语句就可以优化为:


代码如下:

select * from user_order_info inner join (select pin from user_order_info limit 1000000,5) as lim using(pin);
SQL>explain select * from user_order_info limit 1000000,5;
+----+-------------+-----------------+------+---------------+------+---------+------+----------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+------+---------------+------+---------+------+----------+-------+
| 1 | SIMPLE | user_order_info | ALL | NULL | NULL | NULL | NULL | 23131886 | |
+----+-------------+-----------------+------+---------------+------+---------+------+----------+-------+
1 row in set (0.00 sec)
SQL>explain extended select * from user_order_info inner join (select pin from user_order_info limit 1000000,5) as lim using(pin);
+----+-------------+-----------------+--------+---------------+---------+---------+---------+----------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------+--------+---------------+---------+---------+---------+----------+----------+-------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | |
| 1 | PRIMARY | user_order_info | eq_ref | PRIMARY | PRIMARY | 42 | lim.pin | 1 | 100.00 | |
| 2 | DERIVED | user_order_info | index | NULL | PRIMARY | 42 | NULL | 23131886 | 100.00 | Using index |
+----+-------------+-----------------+--------+---------------+---------+---------+---------+----------+----------+-------------+
3 rows in set, 1 warning (0.66 sec)

根据两个explain的对比,可以清晰发现,第一个未使用索引,扫描了23131886行,第二个也扫描了同样的行数,但是使用了索引,效率提高了。这样可以直接使用index得到数据,而不去查询表,当找到需要的数据之后,在与全表join,获得其他的列。

(0)

相关推荐

  • mysql分页时offset过大的Sql优化经验分享

    发现问题 当我们展示一个列表中的内容时,难免会遇到分页问题,因为列表中的内容数量可能很多,但是用户能一次看到的界面大小是有限的,不可能一个界面展示所有的内容,从后端一次性取太多的数据也会给后端造成额外的压力. 通常分页查询的时候会使用这样的语句: SELECT * FROM table where condition1 = 0 and condition2 = 0 and condition3 = -1 and condition4 = -1 order by id asc LIMIT 2000

  • mysql 分页优化解析

    如果你的数据量有几十万条,用户又搜索一些很通俗的词,然后要依次读最后几页重温旧梦.mysql该很悲壮的不停操作硬盘. 所以,可以试着让mysql也存储分页,当然要程序配合.(这里只是提出一个设想,欢迎大家一起讨论) ASP的分页:在ASP系统中有Recordset对象来实现分页,但是大量数据放在内存中,而且不知道什么时候才失效(请ASP高手指点). SQL数据库分页:用存储过程+游标方式分页,具体实现原理不是很清楚,设想如果用一次查询就得到需要的结果,或者是id集,需要后续页时只要按照结果中的I

  • 8种MySQL分页方法总结

    MySQL的分页似乎一直是个问题,有什么优化方法吗?网上看到网上推荐了一些分页方法,但似乎不太可行,你能点评一下吗? 方法1: 直接使用数据库提供的SQL语句 ---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N. ---适应场景: 适用于数据量较少的情况(元组百/千级). ---原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3).Limit限制的是从结果集的M位置处取出N条输出,

  • 如何优化Mysql千万级快速分页

    看例子: 数 据表 collect ( id, title ,info ,vtype) 就这4个字段,其中 title 用定长,info 用text, id 是逐渐,vtype是tinyint,vtype是索引.这是一个基本的新闻系统的简单模型.现在往里面填充数据,填充10万篇新闻. 最后collect 为 10万条记录,数据库表占用硬盘1.6G. OK ,看下面这条sql语句: select id,title from collect limit 1000,10; 很快:基本上0.01秒就OK

  • 优化mysql的limit offset的例子

    经常碰到的一个问题是limit的offset太高,如:limit 100000,20,这样系统会查询100020条,然后把前面的100000条都扔掉,这是开销很大的操作,导致查询很慢.假设所有分页的页面访问频率一样,这样的查询平均扫描表的一半数据.优化的方法,要么限制访问后面的页数,要么提升高偏移的查询效率. 一个简单的优化办法是使用覆盖查询(covering index)查询,然后再跟全行的做join操作.如: 复制代码 代码如下: SQL>select * from user_order_i

  • 详解mysql的limit经典用法及优化实例

    用法一  复制代码 代码如下: SELECT `keyword_rank`.* FROM `keyword_rank` WHERE (advertiserid='59') LIMIT 2 OFFSET 1; 比如这个SQL ,limit后面跟的是2条数据,offset后面是从第1条开始读取. 用法二  复制代码 代码如下: SELECT `keyword_rank`.* FROM `keyword_rank` WHERE (advertiserid='59') LIMIT 2,1; 而这个SQL

  • MYSQL分页limit速度太慢的优化方法

    在mysql中limit可以实现快速分页,但是如果数据到了几百万时我们的limit必须优化才能有效的合理的实现分页了,否则可能卡死你的服务器哦.    当一个表数据有几百万的数据的时候成了问题! 如 * from table limit 0,10 这个没有问题 当 limit 200000,10 的时候数据读取就很慢,可以按照一下方法解决     第一页会很快    PERCONA PERFORMANCE CONFERENCE 2009上,来自雅虎的几位工程师带来了一篇"EfficientPag

  • 使用Limit参数优化MySQL查询的方法

    前些天看了一个老外写的程序,在 MySQL 查询中使用了很多 Limit 关键字,这就让我很感兴趣了,因为在我印象中, Limit 关键字似乎更多被使用 MySQL 数据库的程序员用来做查询分页(当然这也是一种很好的查询优化),那在这里举个例子,假设我们需要一个分页的查询 ,Oracle中一般来说都是用以下 SQL 句子实现: SELECT * FROM ( SELECT a1.*, rownum rownum_ FROM testtable a1 WHERE rownum > 20) WHER

  • 浅谈mysql使用limit分页优化方案的实现

    Mysql limit分页语句用法 与Oracle和MS SqlServer相比,mysql的分页方法简单的让人想哭. --语法: SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset --举例: select * from table limit 5; --返回前5行 select * from table limit 0,5; --同上,返回前5行 select * from table limit 5,10; --返回6

  • MySQL分页Limit的优化过程实战

    前言 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.LIMIT 接受一个或两个数字参数.参数必须是一个整数常量.如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目.初始记录行的偏移

  • mysql查询时offset过大影响性能的原因和优化详解

    前言 mysql查询使用select命令,配合limit,offset参数可以读取指定范围的记录.本文将介绍mysql查询时,offset过大影响性能的原因及优化方法. 准备测试数据表及数据 1.创建表 CREATE TABLE `member` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL COMMENT '姓名', `gender` tinyint(3) unsigned NOT NU

  • 详细介绍mysql中limit与offset的用法

    目录 mysql limit与offset用法 附:Mysql limit offset用法举例 总结 有的时候我们在学习或者工作中会使用到SQL语句,那么介绍一下limit和offset的使用方法. mysql limit与offset用法 mysql里分页一般用limit来实现,例如: 1.select* from user limit 3 表示直接取前三条数据 2.select * from user limit 1,3; 表示取1后面的第2,3,4三条条数据 3.select * fro

  • 浅谈MySQL分页Limit的性能问题

    MySQL的分页查询通常通过limit来实现.limit接收1或2个整数型参数,如果是2个参数,第一个是指定第一个返回记录行的偏移量,第二个是返回记录行的最大数目.初始记录行的偏移量是0.为了与PostgreSQL兼容,limit也支持limit # offset #. 问题: 对于小的偏移量,直接使用limit来查询没有什么问题,但随着数据量的增大,越往后分页,limit语句的偏移量就会越大,速度也会明显变慢. 优化思想:避免数据量大时扫描过多的记录 解决:子查询的分页方式或者JOIN分页方式

  • MySQL 百万级分页优化(Mysql千万级快速分页)

    以下分享一点我的经验 一般刚开始学SQL的时候,会这样写 复制代码 代码如下: SELECT * FROM table ORDER BY id LIMIT 1000, 10; 但在数据达到百万级的时候,这样写会慢死 复制代码 代码如下: SELECT * FROM table ORDER BY id LIMIT 1000000, 10; 也许耗费几十秒 网上很多优化的方法是这样的 复制代码 代码如下: SELECT * FROM table WHERE id >= (SELECT id FROM

随机推荐