http://blog.chinaunix.net/u/29134/showart_1333566.html
【原创】关于MySQL分页的优化
关于分页的优化。
我们知道,在MySQL中分页很简单,直接LIMIT page_no,page_total 就可以了。
可是当记录数慢慢增大时,她就不那么好使了。
这里我们创建摘要表来记录页码和原表之间的关联。
下面为测试数据。
原表:
CREATE TABLE `t_group` (
`id` int(11) NOT NULL auto_increment,
`money` decimal(10,2) NOT NULL,
`user_name` varchar(20) NOT NULL,
`create_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_combination1` (`user_name`,`money`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
原表总记录数:
mysql> select count(*) from t_group;
+----------+
| count(*) |
+----------+
| 10485760 |
+----------+
1 row in set (0.00 sec)
分页表:
CREATE TABLE `t_group_ids` (
`id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`,`group_id`),
KEY `idx_id` (`id`),
KEY `idx_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入分页表数据。当然这里如果你的表主键不是ID,那你得自己想办法搞这个分页表的数据了。这个好实现,就不说了。
mysql> insert into t_group_ids select ceil(id/20),id from t_group;
Query OK, 10485760 rows affected (2 min 56.19 sec)
Records: 10485760 Duplicates: 0 Warnings: 0
现在来看看对比数据。
用普通LIMIT来实现分页。
mysql> select * from t_group where 1 limit 20;
+----+--------+-----------+---------------------+
| id | money | user_name | create_time |
+----+--------+-----------+---------------------+
| 1 | 50.23 | david | 2008-10-23 12:55:49 |
| 2 | 55.23 | livia | 2008-10-23 10:02:09 |
| 3 | 100.83 | leo | 2008-10-23 10:02:22 |
| 4 | 99.99 | lucy | 2008-10-23 10:02:39 |
| 5 | 299.99 | simon | 2008-10-23 10:02:52 |
| 6 | 599.99 | sony | 2008-10-23 10:03:03 |
| 7 | 599.99 | rick | 2008-10-23 10:03:12 |
| 8 | 9.99 | anne | 2008-10-23 10:03:47 |
| 9 | 9.99 | sarah | 2008-10-23 10:04:31 |
| 10 | 900.99 | john | 2008-10-23 10:04:50 |
| 11 | 0.23 | david | 2008-10-23 10:05:31 |
| 12 | 5.23 | livia | 2008-10-23 10:05:31 |
| 13 | 50.83 | leo | 2008-10-23 10:05:31 |
| 14 | 49.99 | lucy | 2008-10-23 10:05:31 |
| 15 | 249.99 | simon | 2008-10-23 10:05:31 |
| 16 | 549.99 | sony | 2008-10-23 10:05:31 |
| 17 | 549.99 | rick | 2008-10-23 10:05:31 |
| 18 | -40.01 | anne | 2008-10-23 10:05:31 |
| 19 | -40.01 | sarah | 2008-10-23 10:05:31 |
| 20 | 850.99 | john | 2008-10-23 10:05:31 |
+----+--------+-----------+---------------------+
20 rows in set (0.01 sec)
用分页表来实现分页。
mysql> select a.* from t_group as a inner join t_group_ids as b where a.id = b.g
roup_id and b.id = 1;
+----+--------+-----------+---------------------+
| id | money | user_name | create_time |
+----+--------+-----------+---------------------+
| 1 | 50.23 | david | 2008-10-23 12:55:49 |
| 2 | 55.23 | livia | 2008-10-23 10:02:09 |
| 3 | 100.83 | leo | 2008-10-23 10:02:22 |
| 4 | 99.99 | lucy | 2008-10-23 10:02:39 |
| 5 | 299.99 | simon | 2008-10-23 10:02:52 |
| 6 | 599.99 | sony | 2008-10-23 10:03:03 |
| 7 | 599.99 | rick | 2008-10-23 10:03:12 |
| 8 | 9.99 | anne | 2008-10-23 10:03:47 |
| 9 | 9.99 | sarah | 2008-10-23 10:04:31 |
| 10 | 900.99 | john | 2008-10-23 10:04:50 |
| 11 | 0.23 | david | 2008-10-23 10:05:31 |
| 12 | 5.23 | livia | 2008-10-23 10:05:31 |
| 13 | 50.83 | leo | 2008-10-23 10:05:31 |
| 14 | 49.99 | lucy | 2008-10-23 10:05:31 |
| 15 | 249.99 | simon | 2008-10-23 10:05:31 |
| 16 | 549.99 | sony | 2008-10-23 10:05:31 |
| 17 | 549.99 | rick | 2008-10-23 10:05:31 |
| 18 | -40.01 | anne | 2008-10-23 10:05:31 |
| 19 | -40.01 | sarah | 2008-10-23 10:05:31 |
| 20 | 850.99 | john | 2008-10-23 10:05:31 |
+----+--------+-----------+---------------------+
20 rows in set (0.00 sec)
取第50W页的数据。
原来表:
mysql> select * from t_group where 1 limit 9999980,20;
+----------+---------+-----------+---------------------+
| id | money | user_name | create_time |
+----------+---------+-----------+---------------------+
| 9999981 | 810.13 | david | 2008-10-23 10:09:24 |
| 9999982 | 815.13 | livia | 2008-10-23 10:09:24 |
| 9999983 | 860.73 | leo | 2008-10-23 10:09:24 |
| 9999984 | 859.89 | lucy | 2008-10-23 10:09:24 |
| 9999985 | 1059.89 | simon | 2008-10-23 10:09:24 |
| 9999986 | 1359.89 | sony | 2008-10-23 10:09:24 |
| 9999987 | 1359.89 | rick | 2008-10-23 10:09:24 |
| 9999988 | 769.89 | anne | 2008-10-23 10:09:24 |
| 9999989 | 769.89 | sarah | 2008-10-23 10:09:24 |
| 9999990 | 1660.89 | john | 2008-10-23 10:09:24 |
| 9999991 | 760.13 | david | 2008-10-23 10:09:24 |
| 9999992 | 765.13 | livia | 2008-10-23 10:09:24 |
| 9999993 | 810.73 | leo | 2008-10-23 10:09:24 |
| 9999994 | 809.89 | lucy | 2008-10-23 10:09:24 |
| 9999995 | 1009.89 | simon | 2008-10-23 10:09:24 |
| 9999996 | 1309.89 | sony | 2008-10-23 10:09:24 |
| 9999997 | 1309.89 | rick | 2008-10-23 10:09:24 |
| 9999998 | 719.89 | anne | 2008-10-23 10:09:24 |
| 9999999 | 719.89 | sarah | 2008-10-23 10:09:24 |
| 10000000 | 1610.89 | john | 2008-10-23 10:09:24 |
+----------+---------+-----------+---------------------+
20 rows in set (4.21 sec)
分页表:
mysql> select a.* from t_group as a inner join t_group_ids as b where a.id = b.g
roup_id and b.id = 500000;
+----------+---------+-----------+---------------------+
| id | money | user_name | create_time |
+----------+---------+-----------+---------------------+
| 9999981 | 810.13 | david | 2008-10-23 10:09:24 |
| 9999982 | 815.13 | livia | 2008-10-23 10:09:24 |
| 9999983 | 860.73 | leo | 2008-10-23 10:09:24 |
| 9999984 | 859.89 | lucy | 2008-10-23 10:09:24 |
| 9999985 | 1059.89 | simon | 2008-10-23 10:09:24 |
| 9999986 | 1359.89 | sony | 2008-10-23 10:09:24 |
| 9999987 | 1359.89 | rick | 2008-10-23 10:09:24 |
| 9999988 | 769.89 | anne | 2008-10-23 10:09:24 |
| 9999989 | 769.89 | sarah | 2008-10-23 10:09:24 |
| 9999990 | 1660.89 | john | 2008-10-23 10:09:24 |
| 9999991 | 760.13 | david | 2008-10-23 10:09:24 |
| 9999992 | 765.13 | livia | 2008-10-23 10:09:24 |
| 9999993 | 810.73 | leo | 2008-10-23 10:09:24 |
| 9999994 | 809.89 | lucy | 2008-10-23 10:09:24 |
| 9999995 | 1009.89 | simon | 2008-10-23 10:09:24 |
| 9999996 | 1309.89 | sony | 2008-10-23 10:09:24 |
| 9999997 | 1309.89 | rick | 2008-10-23 10:09:24 |
| 9999998 | 719.89 | anne | 2008-10-23 10:09:24 |
| 9999999 | 719.89 | sarah | 2008-10-23 10:09:24 |
| 10000000 | 1610.89 | john | 2008-10-23 10:09:24 |
+----------+---------+-----------+---------------------+
20 rows in set (0.03 sec)
我们来取最后一页的数据。
原表:
mysql> select * from t_group where 1 limit 10485740,20;
+----------+---------+-----------+---------------------+
| id | money | user_name | create_time |
+----------+---------+-----------+---------------------+
| 10485741 | 1935.42 | david | 2008-10-23 10:09:24 |
| 10485742 | 1955.42 | livia | 2008-10-23 10:09:24 |
| 10485743 | 2137.82 | leo | 2008-10-23 10:09:24 |
| 10485744 | 2134.46 | lucy | 2008-10-23 10:09:24 |
| 10485745 | 2934.46 | simon | 2008-10-23 10:09:24 |
| 10485746 | 4134.46 | sony | 2008-10-23 10:09:24 |
| 10485747 | 4134.46 | rick | 2008-10-23 10:09:24 |
| 10485748 | 1774.46 | anne | 2008-10-23 10:09:24 |
| 10485749 | 1774.46 | sarah | 2008-10-23 10:09:24 |
| 10485750 | 5338.46 | john | 2008-10-23 10:09:24 |
| 10485751 | 1735.42 | david | 2008-10-23 10:09:24 |
| 10485752 | 1755.42 | livia | 2008-10-23 10:09:24 |
| 10485753 | 1937.82 | leo | 2008-10-23 10:09:24 |
| 10485754 | 1934.46 | lucy | 2008-10-23 10:09:24 |
| 10485755 | 2734.46 | simon | 2008-10-23 10:09:24 |
| 10485756 | 3934.46 | sony | 2008-10-23 10:09:24 |
| 10485757 | 3934.46 | rick | 2008-10-23 10:09:24 |
| 10485758 | 1574.46 | anne | 2008-10-23 10:09:24 |
| 10485759 | 1574.46 | sarah | 2008-10-23 10:09:24 |
| 10485760 | 5138.46 | john | 2008-10-23 10:09:24 |
+----------+---------+-----------+---------------------+
20 rows in set (4.88 sec)
分页表:
mysql> select a.* from t_group as a inner join t_group_ids as b where a.id = b.g
roup_id and b.id = 524288;
+----------+---------+-----------+---------------------+
| id | money | user_name | create_time |
+----------+---------+-----------+---------------------+
| 10485741 | 1935.42 | david | 2008-10-23 10:09:24 |
| 10485742 | 1955.42 | livia | 2008-10-23 10:09:24 |
| 10485743 | 2137.82 | leo | 2008-10-23 10:09:24 |
| 10485744 | 2134.46 | lucy | 2008-10-23 10:09:24 |
| 10485745 | 2934.46 | simon | 2008-10-23 10:09:24 |
| 10485746 | 4134.46 | sony | 2008-10-23 10:09:24 |
| 10485747 | 4134.46 | rick | 2008-10-23 10:09:24 |
| 10485748 | 1774.46 | anne | 2008-10-23 10:09:24 |
| 10485749 | 1774.46 | sarah | 2008-10-23 10:09:24 |
| 10485750 | 5338.46 | john | 2008-10-23 10:09:24 |
| 10485751 | 1735.42 | david | 2008-10-23 10:09:24 |
| 10485752 | 1755.42 | livia | 2008-10-23 10:09:24 |
| 10485753 | 1937.82 | leo | 2008-10-23 10:09:24 |
| 10485754 | 1934.46 | lucy | 2008-10-23 10:09:24 |
| 10485755 | 2734.46 | simon | 2008-10-23 10:09:24 |
| 10485756 | 3934.46 | sony | 2008-10-23 10:09:24 |
| 10485757 | 3934.46 | rick | 2008-10-23 10:09:24 |
| 10485758 | 1574.46 | anne | 2008-10-23 10:09:24 |
| 10485759 | 1574.46 | sarah | 2008-10-23 10:09:24 |
| 10485760 | 5138.46 | john | 2008-10-23 10:09:24 |
+----------+---------+-----------+---------------------+
20 rows in set (0.01 sec)
总结:我们看到,当表记录数增加时,LIMIT的性能随着线性增长。而当我们存放了页码与主键的关联后,性能大增。
分享到:
相关推荐
MySQL 百万级分页优化(Mysql千万级快速分页),主要解决大数量级的优化
到此这篇关于mysql分页的limit参数的文章就介绍到这了,更多相关mysql分页limit参数内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网! 您可能感兴趣的文章:详解MySQL的limit...
如何优化Mysql千万级快速分页,详尽解决方案!
本文档针对mysql分页之limit慢的问题,使用联合索引在大数据量的情况下优化limit分页的性能
主要介绍了MySQL优化案例系列-mysql分页优化,需要的朋友可以参考下
优化mysql分页查询速度。
mysql分页查询方法及其优化方法一语句样式: mysql中,可用如下方法: select * from 表名称 limit offset, pagesize使
所以,可以试着让mysql也存储分页,当然要程序配合。(这里只是提出一个设想,欢迎大家一起讨论) ASP的分页:在ASP系统中有Recordset对象来实现分页,但是大量数据放在内存中,而且不知道什么时候才失效(请ASP高手...
JSP+MYSQL+Java类优化分页的实例
百万级数据库记录下的Mysql快速分页优化实例 该文档提供了很多MySQL优化的实例 有必要看以下
主要介绍了MYSQL分页limit速度太慢的优化方法,需要的朋友可以参考下
mysql limit分页优化 同样是取10条数据 select * from yanxue8_visit limit 10000,10 和 select * from yanxue8_visit limit 0,10 就不是一个数量级别的。 网上也很多关于limit的五条优化准则,都是翻译自MySQL...
传统的mysql分页查询 select * from table limit n , m MySQL 执行此类SQL时需要先分页(默认一页1000条数据)通过全表扫描到N行,然后再去取M行。对于此类操作,获取前面少数几行数据会很快,但是随着扫描的记录数越...
MySQL大数据量分页查询方法及其优化
教程包含mysql优化思路讲解、索引优化、分页优化、主从复制集群配置、分区、事务讲解以及其他常见问题讲解等
主要介绍了Mysql Limit 分页查询优化的相关资料,非常不错,介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
分页程序原理很简单,这里就不多说了,本篇文章主要说的是在数据表记录量比较大的情况下,如何将分页SQL做到更优化,让MySQL执行的更快的方法。
在mysql中limit可以实现快速分页,但是如果数据到了几百万时我们的limit必须优化才能有效的合理的实现分页了,否则可能卡死你的服务器哦。
主要介绍了mysql分页原理和高效率的mysql分页查询语句,大家参考使用吧