MySQL具体解释(19)----------海量数据分页查询优化
分页的详细解说解说请看http://blog.csdn.net/u011225629/article/details/46775947
查看代码打印1 SELECT * FROM table ORDER BY id LIMIT 1000,10;
以上SQL语句在原理上和在实际操作中是不会存在什么问题,可是当table表的数据量达到几十万以上的时候。上面的语句运行一遍,可能会要运行个十几秒的时间,而且当页数越靠后的话,运行的时间会越长。这个时候我们就须要找到一种更快的查询办法来替代这样的操作了。
网上已经有非常多优化的方法。基本都是这种:
查看代码打印1 SELECT * FROM table WHERE id >= (SELECT id FROM table LIMIT 1000000, 1) LIMIT 10;
以上SQL语句是一个不错的解决方法。分页查询的速度基本会保持在1秒之内。但据经验总结得出另一种更好的办法,例如以下:
查看代码打印1 SELECT * FROM table WHERE id BETWEEN 1000000 AND 1000010;
相比以上的解决的方法,在速度上还会快了不少。
另外分享两个关于查询的技巧:
(1)假设须要查询 id 不是连续的一段,最佳的做法就是先找出 id ,然后用 in 查询:
查看代码打印1 SELECT * FROM table WHERE id IN(10000, 100000, 1000000...);
(2)当查询字段一较长字符串的时候,表设计时要为该字段多加一个字段,如存储网址的字段。在须要查询该字段的时候,不要直接查询字符串,效率低下。应该查诡该字串的crc32或md5值。
怎样优化Mysql千万级高速分页。下面摘抄与网上,读者自行參考。
MySql 性能究竟能有多高?用了php半年多,真正如此深入的去思考这个问题还是从前天開始。有过痛苦有过绝望。到如今充满信心!MySql 这个数据库绝对是适合dba级的高手去玩的,一般做一点1万篇新闻的小型系统怎么写都能够。用xx框架能够实现高速开发。
但是数据量到了10万,百万至千万,他的性能还能那么高吗?一点小小的失误,可能造成整个系统的改写。甚至更本系统无法正常执行。好了。不那么多废话了。用事实说话,看样例:
数据表 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秒到了一个数量级。从这里開始有人提出了分表的思路。这个和dis #cuz 论坛是一样的思路。思路例如以下:
建一个索引表: 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无法用索引是错误的!
有了这个结论,就能够非常easy的应用于轻量级框架了:
通过简单的变换,事实上思路非常easy:
(1)通过优化索引。找出id。并拼成 “123,90000,12000″ 这种字符串。
(2)第2次查询找出结果。小小的索引+一点点的修改就使mysql 能够支持百万甚至千万级的高效分页。
通过这里的样例,我反思了一点:对于大型系统。PHP千万不能用框架,尤其是那种连sql语句都看不到的框架!
由于開始对于我的轻量级框架都差点崩溃!仅仅适合小型应用的高速开发。对于ERP,OA,大型站点,数据层包含逻辑层的东西都不能用框架。假设程序猿失去了对sql语句的把控,那项目的风险将会成几何级数添加!
尤其是用mysql 的时候。mysql 一定须要专业的dba 才干够发挥他的最佳性能。
一个索引所造成的性能区别可能是上千倍。
MySQL具体解释(19)----------海量数据分页查询优化的更多相关文章
- mysql数据库千万级别数据的查询优化和分页测试
原文地址:原创 mysql数据库千万级别数据的查询优化和分页测试作者:于堡舰 本文为本人最近利用几个小时才分析总结出的原创文章,希望大家转载,但是要注明出处 http://blog.sina.com. ...
- 数据库MySQL 之 索引原理与慢查询优化
数据库MySQL 之 索引原理与慢查询优化 浏览目录 索引介绍方法类型 聚合索引辅助索引 测试索引 正确使用索引 组合索引 注意事项 查询计划 慢查询日志 大数据量分页优化 一.索引介绍方法类型 1. ...
- MySQL——优化嵌套查询和分页查询
优化嵌套查询 嵌套查询(子查询)可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中.嵌套查询写起来简单,也容易理解.但是,有时候可以被更有效率的连接(JOIN ...
- 第二百八十八节,MySQL数据库-索引、limit分页、执行计划、慢日志查询
MySQL数据库-索引.limit分页.执行计划.慢日志查询 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获 ...
- 十、mysql之索引原理与慢查询优化
mysql之索引原理与慢查询优化 一.介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还 ...
- MySQL学习之路 一 : MySQL 5.7.19 源码安装
MySQL 5.7.19 源码安装 查看系统: # cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) 安装依赖包 # yum - ...
- MySQL大数据量快速分页实现(转载)
在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢? 般刚开始学SQL语句的时候,会这 ...
- WordPress 4.8 安装配置教程 (基于 centos 7.3, php 7.0, mysql 5.7.19, nginx 1.12.1)
最近想要整个 blog,记录自己工作.学习中的点滴.Wordpress 自然是首选,因为内容才是关键,所以也就不怕别人说太 low.网上大部份都是讲 wordpress 配合 apache 的安装教程 ...
- mysql_linux(centos7 mysql 5.7.19)
centos7 mysql 5.7.19安装 1.解压文件 [root@centos3 ~]# tar -zxvf mysql-5.7.19-linux-glibc2.12-x86_64.tar.g ...
随机推荐
- 用Servlet实现聊天室设计
实验一 Servlet编程 一.实验目的 1.熟悉Java EE编程环境JDK和NetBeans的安装,配置和使用: 2.掌握Servlet的编写及部署: 3.掌握Servlet的工作原理和编程接 ...
- scrapy中运行爬虫时出现twisted critical unhandled error错误
1. 试试这条命令: twisted critical unhandled error on scrapy tutorial python python27\scripts\pywin32_posti ...
- Android SQLiteDatabase使用总结
SQLiteDatabase数据库操作 1.创建一个继承了类SQLiteOPenHelper类复写相应的方法,和构造函数 2.然后创建一个类,定义一个私有变量(上述类的实例化对象),在构造函数中进行初 ...
- Ant Table组件
http://www.cnblogs.com/hujunzheng/p/5689650.html React中使用Ant Table组件 v一.Ant Design of React http:/ ...
- javascript - 工作笔记 (事件绑定)
背景: 目前所做的项目,只能使用的是原生的javascript.对于javascript的事件绑定想必大家都懂得语法: 1,在标签中使用属性调用方法:<div onclick="AAA ...
- sql server 2012 镜像和出现的问题
镜像安装的环境: 主机:win server 2012 , sql server 2012 ,ip:192.168.1.189 PC账户:administrator 备机:win server 20 ...
- 使用C#开发Metro 风格应用的路线图 -- 触屏操作
原文 http://www.cnblogs.com/icuit/archive/2012/05/01/2478312.html win8支持多点触摸技术,而我们在屏幕上所做的各种操作,也最终转换为输入 ...
- 从零开始学 iOS 开发的15条建议
事情困难是事实,再困难的事还是要每天努力去做是更大的事实. 因为我是一路自学过来的,并且公认没什么天赋的前提下,进步得不算太慢,所以有很多打算从零开始的朋友会问我,该怎么学iOS开发.跟粉丝群的朋友交 ...
- JAVA Layout
/** * baidu :组件不会直接放到框架上,而是放在若干个面板上,这些面板再放到窗格上? * 实际上在JFrame上可直接添加Jbutton * * BorderLayout Flow ...
- k8s 集群基本概念
一.概述: kubernetes是google开源的容器集群管理系统,提供应用部署.维护.扩展机制等功能,利用kubernetes能方便管理跨集群运行容器化的应用,简称:k8s(k与s之间有8个字母) ...