`
saybody
  • 浏览: 902807 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

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分页优化的核心概念 分页是数据库操作中的常见需求,特别是在Web应用中,用户界面通常会以分页的形式展示数据列表。MySQL通过`LIMIT`子句来实现分页功能,但是当数据量巨大时,传统的`LIMIT`分页方法可能...

    xianglujun#handbook#Mysql分页优化方法1

    mysql分页查询方法及其优化方法一语句样式: mysql中,可用如下方法: select * from 表名称 limit offset, pagesize使

    MySQL优化案例系列-mysql分页优化

    本文将深入探讨MySQL分页查询的优化技术。 ### 分页查询的传统方法及问题 在MySQL中,通常使用`ORDER BY ... LIMIT start, offset`的方式来进行分页查询。这种查询方式是通过给定一个起始位置(start)和偏移量...

    MySQL分页优化

    MySQL分页优化是数据库性能调优的一个重要环节,特别是在处理大量数据时,高效的分页策略能够显著提升系统响应速度和用户体验。本文将深入探讨MySQL分页优化的原理、问题及解决方案。 首先,我们要理解MySQL分页的...

    mysql 分页优化解析

    MySQL 分页优化是数据库性能优化的一个重要方面,尤其是在处理大量数据时。传统的`LIMIT m, n`方法在简单查询中表现良好,但如果涉及到复杂的搜索条件和排序,性能可能会急剧下降。这是因为MySQL可能需要扫描全部...

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

    以下是一些针对MySQL `LIMIT` 分页速度慢的优化方法: 1. **避免大`OFFSET`值**: 当`OFFSET`值很大时,MySQL会跳过很多行才能到达需要返回的数据。例如,`LIMIT 200000, 10`需要扫描200010行,这是非常低效的。...

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

    ### MySQL 百万级分页优化(Mysql千万级快速分页) #### 背景与挑战 在处理大规模数据集时,例如拥有数百万乃至数千万条记录的数据库表,传统的分页查询方法可能会遇到性能瓶颈。特别是使用`LIMIT`进行分页时,随着...

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

    MySQL 千万级快速分页优化方案 在实际开发中,我们经常会遇到 MySQL 数据库的性能问题,特别是在处理千万级数据时,分页查询的性能会变得非常慢。在这篇文章中,我们将探讨如何优化 MySQL 千万级快速分页,详细介绍...

    高效的MySQL分页

    总结来说,实现高效的MySQL分页查询需要考虑索引优化、使用新的SQL特性,以及借助合适的开发工具。同时,持续关注数据库性能监控,及时调整和优化查询策略,对于保持系统稳定和提升用户体验具有重要意义。

    mysql数据库实现分页

    总结,MySQL的分页功能是处理大数据量查询的关键技术,通过合理使用`LIMIT`和`OFFSET`,配合索引优化,可以有效地提高查询效率,提升用户交互体验。同时,随着版本升级,MySQL提供了更多分页策略和技术,如窗口函数...

    nodejs mysql 实现分页的方法

    分页可以有效提高页面的响应速度,并优化用户的浏览体验。本文主要介绍了在Node.js环境下,如何使用MySQL数据库实现分页功能。 首先,分页的基本思路是确定每页显示的数据条目数(即页面大小),然后根据当前页码...

    JSP+MySql分页组件

    【JSP+MySQL分页组件】是Web开发中常见的功能,用于处理大量数据时提高页面加载速度和用户体验。在Web应用程序中,一次性加载所有数据可能导致页面响应慢,尤其是在数据库存储的数据量庞大的情况下。分页技术可以...

    mysql分页之limit优化技巧

    本文档针对mysql分页之limit慢的问题,使用联合索引在大数据量的情况下优化limit分页的性能

    mysql分页的limit参数简单示例

    Mysql的分页的两个参数 select * from user limit 1,2 ... 您可能感兴趣的文章:详解MySQL的limit用法和分页查询语句的性能分析MYSQL分页limit速度太慢的优化方法mysql limit分页优化方法分享Mysql limit

    PHP MYSQL分页代码

    本资源"PHP MYSQL分页代码"提供了一个实用的解决方案,结合了PHP和MySQL两种技术来实现高效的数据分页功能。 首先,让我们深入了解PHP和MySQL在分页中的角色。PHP是一种广泛使用的服务器端脚本语言,常用于动态网站...

    easyUI+MySQL分页

    本项目“easyUI+MySQL分页”旨在教你如何利用easyUI框架与MySQL数据库相结合,实现在Web页面上展示分页数据的效果。在这个过程中,我们将涉及到前端的JavaScript库easyUI,以及后端的MySQL数据库和可能用到的Java...

    关于Mysql分页的两种方法,假分页和limit分页

    此外,还有一些其他策略可以优化MySQL的分页性能,例如,使用存储过程来封装分页查询,或者使用游标进行逐页读取。还可以设计更合理的数据结构和业务逻辑,例如,使用时间戳代替主键进行排序,这样可以避免因主键值...

    java-web-mysql 分页demo

    二、MySQL分页查询 在MySQL中,我们可以使用`LIMIT`和`OFFSET`关键字来实现分页。`LIMIT`用于指定每页显示的数据条数,`OFFSET`用于指定从哪一条记录开始取数据。例如,要获取第2页(每页5条数据)的信息,SQL语句...

Global site tag (gtag.js) - Google Analytics