首页 数据库 mysql教程 如何优化Mysql千万级快速分页_MySQL

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

Jun 01, 2016 pm 01:44 PM
快速 数字 数据库优化

bitsCN.com

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,再看下面的
select id,title from collect limit 90000,10; 从9万条开始分页,结果?
8-9秒完成,my god 哪出问题了????其实要优化这条数据,网上找得到答案。看下面一条语句:
select id from collect order by id limit 90000,10; 很快,0.04秒就OK。 为什么?因为用了id主键做索引当然快。网上的改法是:
select id,title from collect where id>=(select id from collect order by id limit 90000,1) limit 10;
这就是用了id做索引的结果。可是问题复杂那么一点点,就完了。看下面的语句
select id from collect where vtype=1 order by id limit 90000,10; 很慢,用了8-9秒!
到了这里我相信很多人会和我一样,有崩溃感觉!vtype 做了索引了啊?怎么会慢呢?vtype做了索引是不错,你直接 select id from collect where vtype=1 limit 1000,10; 是很快的,基本上0.05秒,可是提高90倍,从9万开始,那就是0.05*90=4.5秒的速度了。和测试结果8-9秒到了一个数量级。从这里开始有人 提出了分表的思路,这个和discuz 论坛是一样的思路。思路如下:
建一个索引表: t (id,title,vtype) 并设置成定长,然后做分页,分页出结果再到 collect 里面去找info 。 是否可行呢?实验下就知道了。
10万条记录到 t(id,title,vtype) 里,数据表大小20M左右。用
select id from t where vtype=1 order by id limit 90000,10; 很快了。基本上0.1-0.2秒可以跑完。为什么会这样呢?我猜想是因为collect 数据太多,所以分页要跑很长的路。limit 完全和数据表的大小有关的。其实这样做还是全表扫描,只是因为数据量小,只有10万才快。OK, 来个疯狂的实验,加到100万条,测试性能。
加了10倍的数据,马上t表就到了200多M,而且是定长。还是刚才的查询语句,时间是0.1-0.2秒完成!分表性能没问题?错!因为我们的limit还是9万,所以快。给个大的,90万开始
select id from t where vtype=1 order by id limit 900000,10; 看看结果,时间是1-2秒!
why ?? 分表了时间还是这么长,非常之郁闷!有人说定长会提高limit的性能,开始我也以为,因为一条记录的长度是固定的,mysql 应该可以算出90万的位置才对啊? 可是我们高估了mysql 的智能,他不是商务数据库,事实证明定长和非定长对limit影响不大? 怪不得有人说 discuz到了100万条记录就会很慢,我相信这是真的,这个和数据库设计有关!
难道MySQL 无法突破100万的限制吗???到了100万的分页就真的到了极限???
答案是: NO !!!! 为什么突破不了100万是因为不会设计mysql造成的。下面介绍非分表法,来个疯狂的测试!一张表搞定100万记录,并且10G 数据库,如何快速分页!
好了,我们的测试又回到 collect表,开始测试结论是: 30万数据,用分表法可行,超过30万他的速度会慢道你无法忍受!当然如果用分表+我这种方法,那是绝对完美的。但是用了我这种方法后,不用分表也可以完美解决!
答案就是:复合索引! 有一次设计mysql索引的时候,无意中发现索引名字可以任取,可以选择几个字段进来,这有什么用呢?开始的select id from collect order by id limit 90000,10; 这么快就是因为走了索引,可是如果加了where 就不走索引了。抱着试试看的想法加了 search(vtype,id) 这样的索引。然后测试
select id from collect where vtype=1 limit 90000,10; 非常快!0.04秒完成!
再测试: select id ,title from collect where vtype=1 limit 90000,10; 非常遗憾,8-9秒,没走search索引!
再测试:search(id,vtype),还是select id 这个语句,也非常遗憾,0.5秒。
综上:如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!
完美解决了分页问题了。可以快速返回id就有希望优化limit , 按这样的逻辑,百万级的limit 应该在0.0x秒就可以分完。看来mysql 语句的优化和索引时非常重要的!
好了,回到原题,如何将上面的研究成功快速应用于开发呢?如果用复合查询,我的轻量级框架就没的用了。分页字符串还得自己写,那多麻烦?这里再看一个例子,思路就出来了:
select * from collect where id in (9000,12,50,7000); 竟然 0秒就可以查完!
mygod ,mysql 的索引竟然对于in语句同样有效!看来网上说in无法用索引是错误的!
有了这个结论,就可以很简单的应用于轻量级框架了:
代码如下:
$db=dblink();
$db->pagesize=20;
$sql="select id from collect where vtype=$vtype";
$db->execute($sql);
$strpage=$db->strpage(); //将分页字符串保存在临时变量,方便输出
while($rs=$db->fetch_array()){
$strid.=$rs['id'].',';
}
$strid=substr($strid,0,strlen($strid)-1); //构造出id字符串
$db->pagesize=0; //很关键,在不注销类的情况下,将分页清空,这样只需要用一次数据库连接,不需要再开;
$db->execute("select id,title,url,sTime,gTime,vtype,tag from collect where id in ($strid)");
fetch_array()): ?>


 
 
 
 
 
 
 



echo $strpage;
通过简单的变换,其实思路很简单:1)通过优化索引,找出id,并拼成 "123,90000,12000" 这样的字符串。2)第2次查询找出结果。
小小的索引+一点点的改动就使mysql 可以支持百万甚至千万级的高效分页!
通过这里的例子,我反思了一点:对于大型系统,PHP千万不能用框架,尤其是那种连sql语句都看不到的框架!因为开始对于我的轻量级框架都差点崩 溃!只适合小型应用的快速开发,对于ERP,OA,大型网站,数据层包括逻辑层的东西都不能用框架。如果程序员失去了对sql语句的把控,那项目的风险将 会成几何级数增加!尤其是用mysql 的时候,mysql 一定需要专业的dba 才可以发挥他的最佳性能。一个索引所造成的性能差别可能是上千倍!
PS: 经过实际测试,到了100万的数据,160万数据,15G表,190M索引,就算走索引,limit都得0.49秒。所以分页最好别让别人看到10万条以后的数据, 要不然会很慢!就算用索引。经过这样的优化,mysql到了百万级分页是个极限!但有这样的成绩已经很不错,如果你是用sqlserver肯定卡死!而 160万的数据用 id in (str) 很快,基本还是0秒。如果这样,千万级的数据,mysql应该也很容易应付。

作者“ERDP技术架构”

bitsCN.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

理解SpringBoot和SpringMVC之间的差异及比较 理解SpringBoot和SpringMVC之间的差异及比较 Dec 29, 2023 am 09:20 AM

对比SpringBoot与SpringMVC,了解它们的差异随着Java开发的不断发展,Spring框架已经成为了许多开发人员和企业的首选。在Spring的生态系统中,SpringBoot和SpringMVC是两个非常重要的组件。虽然它们都是基于Spring框架的,但在功能和使用方式上却有一些区别。本文将重点对比一下SpringBoot与Sprin

Win11系统中'我的电脑”路径有何不同?快速查找方法! Win11系统中'我的电脑”路径有何不同?快速查找方法! Mar 29, 2024 pm 12:33 PM

Win11系统中“我的电脑”路径有何不同?快速查找方法!随着Windows系统的不断更新,最新的Windows11系统也带来了一些新的变化和功能。其中一个常见的问题是用户在Win11系统中找不到“我的电脑”的路径,这在之前的Windows系统中通常是很简单的操作。本文将介绍Win11系统中“我的电脑”的路径有何不同,以及快速查找的方法。在Windows1

WordPress 网站搭建指南:快速搭建个人网站 WordPress 网站搭建指南:快速搭建个人网站 Mar 04, 2024 pm 04:39 PM

WordPress网站搭建指南:快速搭建个人网站随着数字化时代的到来,拥有一个个人网站已经成为了一种时尚和必要。而WordPress作为最受欢迎的网站搭建工具,让搭建个人网站变得更加容易和便捷。本文将为大家提供一个快速搭建个人网站的指南,包含具体的代码示例,希望可以帮助到想要拥有自己网站的朋友们。第一步:购买域名和主机在开始搭建个人网站之前,首先要购买自己

Hibernate 如何优化数据库查询性能? Hibernate 如何优化数据库查询性能? Apr 17, 2024 pm 03:00 PM

优化Hibernate查询性能的技巧包括:使用延迟加载,推迟加载集合和关联对象;使用批处理,组合更新、删除或插入操作;使用二级缓存,将经常查询的对象存储在内存中;使用HQL外连接,检索实体及其相关实体;优化查询参数,避免SELECTN+1查询模式;使用游标,以块的方式检索海量数据;使用索引,提高特定查询的性能。

Spring Boot的性能优化秘籍:打造疾风般快速的应用 Spring Boot的性能优化秘籍:打造疾风般快速的应用 Feb 25, 2024 pm 01:01 PM

SpringBoot是一款广受欢迎的Java框架,以其简单易用和快速开发而著称。然而,随着应用程序的复杂性增加,性能问题可能会成为瓶颈。为了帮助您打造疾风般快速的springBoot应用,本文将分享一些实用的性能优化秘诀。优化启动时间应用程序的启动时间是用户体验的关键因素之一。SpringBoot提供了多种优化启动时间的途径,例如使用缓存、减少日志输出和优化类路径扫描。您可以通过在application.properties文件中设置spring.main.lazy-initialization

分享PyCharm中快速注释代码的技巧,提高工作效率 分享PyCharm中快速注释代码的技巧,提高工作效率 Jan 04, 2024 pm 12:02 PM

效率提升!PyCharm中快速注释代码的方法分享在日常的软件开发工作中,我们经常需要注释掉一部分代码进行调试或者调整。如果手动逐行添加注释,这无疑会增加我们的工作量和耗费时间。而PyCharm作为一款强大的Python集成开发环境,提供了快速注释代码的功能,大大提升了我们的开发效率。本文将分享一些在PyCharm中快速注释代码的方法,并提供具体的代码示例。单

前端开发中sessionStorage的优点及应用案例分析 前端开发中sessionStorage的优点及应用案例分析 Jan 11, 2024 pm 02:51 PM

sessionStorage在前端开发中的优势与应用案例分析随着Web应用的发展,前端开发的需求也越来越多样化。前端开发人员需要使用各种工具和技术来提高用户体验,其中,sessionStorage是一个非常有用的工具。本文将介绍sessionStorage在前端开发中的优势,以及几个具体的应用案例。sessionStorage是HTML5提供的一种本地存储方

Java Spring Boot Security性能优化:让你的系统飞起来 Java Spring Boot Security性能优化:让你的系统飞起来 Feb 19, 2024 pm 05:27 PM

一、代码优化避免使用过多的安全注解:在Controller和Service中,尽量减少使用@PreAuthorize和@PostAuthorize等注解,这些注解会增加代码的执行时间。优化查询语句:使用springDataJPA时,优化查询语句可以减少数据库的查询时间,从而提高系统性能。缓存安全信息:将一些常用的安全信息缓存起来,可以减少数据库的访问次数,提高系统的响应速度。二、数据库优化使用索引:在经常被查询的表上创建索引,可以显着提高数据库的查询速度。定期清理日志和临时表:定期清理日志和临时

See all articles