`
lwcheng1985
  • 浏览: 95988 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【原创】关于MySQL分页的优化

阅读更多
摘自:http://blog.chinaunix.net/u/29134/showart_1333566.html
关于分页的优化。
我们知道,在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的性能随着线性增长。而当我们存放了页码与主键的关联后,性能大增。
http://blog.chinaunix.net/u/29134/showart_1333566.html
分享到:
评论

相关推荐

    原创经典实例spring+mybatis+分页+百万数据

    总的来说,这个"原创经典实例spring+mybatis+分页+百万数据"涵盖了Spring框架的使用、MyBatis的映射方式、以及大数据量下的分页策略。无论你是初学者还是经验丰富的开发者,都可以从中受益,提升自己的技能水平。...

    原创的一个PHP+MYSQL论坛

    【标题】"原创的一个PHP+MYSQL论坛"是一个基于PHP编程语言和MySQL数据库系统的论坛软件解决方案。这个论坛系统是由开发者独立创建的,旨在提供一个在线讨论平台,用户可以在上面发表话题、进行互动交流。PHP是一种...

    原创技术:史上最灵活,强大的分页框架

    【标题】:“原创技术:史上最灵活,强大的分页框架” 在IT行业中,分页是数据库查询和网页展示数据时常用的一种技术,它能够有效地管理大量数据,提高用户体验,并减轻服务器负担。这篇原创技术文章声称介绍了一个...

    DBGrid分页程序(原创)

    1. **数据获取**:连接到数据库并执行SQL查询,通常会包含`OFFSET`和`FETCH NEXT`子句(在SQL Server 2005及更高版本中)或`LIMIT`和`OFFSET`(在MySQL等其他数据库系统中)来获取特定页的数据。 2. **数据绑定**:...

    mysqloraclesqlser2000数据库分页

    预计这个PPT文档会深入讲解这些分页技术的原理、优缺点,以及如何在实际项目中结合Java进行高效、优化的分页设计。可能还会包含性能测试、最佳实践、注意事项等内容。 综上所述,"mysqloraclesqlser2000数据库分页...

    (原创)sql设计优化经验

    19. **统计查询优化**:`COUNT(*)`操作消耗资源,应尽量避免,使用分页语句如`LIMIT`来替代。 20. **同类型比较**:确保比较的列具有相同的类型,例如`WHERE remark=123`应改为`WHERE remark='123'`。 遵循这些...

    74cms 骑士人才系统 v4.1.23 正式版 人才招聘系统源码

    全部代码都为骑士网络原创,有着完全的知识产权。凭借骑士网络的不断创新精神和认真的工作态度,骑士人才系统已成国内同类软件中的最好用的人才系统。 骑士cms人才系统 v4.1.23 bulid2017.02.17 更新内容: 修复 ...

    基于ssm原创音乐小程序源码数据库文档.zip

    5. **安全与性能优化**:项目可能考虑了安全性措施,如使用HTTPS、参数校验、防止SQL注入等,同时也会有性能优化策略,如分页查询、缓存机制、负载均衡等。 6. **测试与部署**:项目开发完成后,需要进行单元测试、...

    原创jsp实现BBS论坛系统源代码

    8. **分页显示**:为了提高用户体验,论坛的帖子列表通常会实现分页显示,这涉及到数据库查询优化和前端页面的分页逻辑。 9. **Ajax异步更新**:为了提升交互性,部分操作可能采用Ajax技术实现页面的无刷新更新,...

    新闻资讯网站源码 带手机版和采集_源码下载.zip

    4、栏目页下拉滚动加载分页,改善阅读体验 5、会员系统二次开发,优化功能及界面 6、前台AJAX登录及注册,并整合QQ登录功能 7、生成百度新闻协议和标签云,利于站长SEO推广 8、定时更新首页,频道栏目,手机站等静态...

    网站网页源码模板 (302).zip

    同时,为了优化用户体验,SEO(搜索引擎优化)和性能优化也是必不可少的考虑因素。 总之,“网站网页源码模板 (302).zip”提供了一套完整的网页设计方案,可以帮助开发者快速启动项目,减少从零开始设计和编码的...

    图片搜索引擎网站模板是一款绿色简洁的图片照片搜索网站模板下载。.zip源码资源下载

    4. **分页与加载更多**:由于图片数量可能庞大,分页和无限滚动加载设计能帮助用户逐步加载内容,避免一次性加载过多导致页面卡顿。 5. **响应式布局**:考虑到不同设备的访问,模板应具备响应式设计,确保在手机、...

    asp+sql论坛设计

    8. **SEO优化**:为了提升论坛在搜索引擎中的可见性,需遵循SEO最佳实践,如使用合适的元标签、URL结构友好、内容原创等。 9. **前端技术**:虽然主要关注的是ASP和SQL,但HTML、CSS和JavaScript也是不可或缺的,...

    DOYO通用建站系统 2.3.rar

    7、loop、sql标签增加分页功能。8、html生成目录增加栏目目录标签9、优化远程图片自动获取功能,图片抓取更精准,优化验证码显示。10、调整会员登陆状态、评论为ajax刷新,实现静态化下的实时更新。11、优化html静态...

    asp.net作业在线提交系统的设计与实现(源代码+论文).zip

    3. **数据库交互**:系统需要存储学生、教师、作业和提交的信息,因此可能使用了ADO.NET或Entity Framework进行数据库操作,通过SQL Server、MySQL或其他关系型数据库存储数据。 4. **用户界面**:ASP.NET提供多种...

    青岛人才网 Ajian美化版

    9. **用户体验**:除了视觉美观,网站可能还包含一些提高用户体验的设计,如分页加载、搜索过滤、职位推荐等,这些都是通过JavaScript和服务器端逻辑共同实现的。 10. **版本控制**:作为一个完整的源码项目,可能...

    葵堆小说php小偷网站程序.7z

    7. **性能优化**:由于可能会频繁地抓取和处理大量数据,所以要考虑性能优化,如缓存机制(例如使用Memcached或Redis)、分页加载、异步处理等。 8. **安全防护**:考虑到可能的XSS(跨站脚本攻击)和SQL注入攻击,...

    PHP写的用户问答系统源码

    - 分页:为了提高加载速度,通常会对结果进行分页显示,避免一次性加载大量数据。 总结来说,这个PHP问答系统源码展示了如何利用PHP实现用户身份验证、数据交互、界面设计以及安全性控制等关键功能。对于初学者来...

    基于springboot的乐器社区网站源码数据库.docx

    - **分页查询**:对于大量数据的查询,采用分页机制,提高查询效率。 综上所述,基于SpringBoot的乐器社区网站不仅可以满足用户对于乐器购买、在线学习的需求,还能够通过高效的架构设计和技术选型,实现系统的稳定...

Global site tag (gtag.js) - Google Analytics