日期:2014-05-16  浏览次数:20747 次

【转】MySQL海量数据分页Limit优化

?

MySQL Limit的使用方法:?


  在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能。SELECT * FROM table_name LIMIT start, end?


1、LIMIT子句可以被用于强制SELEDT语句返回指定的记录数。LIMIT接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是0(而不是1)。?

mysql>SELECT * FROM table LIMIT 5,10; //检索记录行6-15?


2、为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为-1:?

mysql>SELECT * FROM table LIMIT 95,-1;//检索记录行96-last.?


3、如果只给定一个参数,它表示返回最大的记录行数目:?

mysql>SELECT * FROM table LIMIT 5; //检索前5条记录行(换句话说,LIMIT n等价于LIMIT 0,n)?


====================================================================

MySQL Limit海量(百万、千万级)数据优化解决方案:?


  MySQL这个数据库绝对是适合dba级的高手去玩的,一般做一点1万篇新闻的小型系统怎么写都可以,用xx框架可以实现快速开发。可是数据量到了10万,百万至千万,他的性能还能那么高吗?一点小小的失误,可能造成整个系统的改写,甚至更本系统无法正常运行!好了,不那么多废话了。用事实说话,看例子:?

? ? 数据表collect(id,title,info,vtype)就这4个字段,其中id是自动增长,title用定长,info用text,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秒完成,mygod哪出问题了????


其实要优化这条数据,网上找得到答案。看下面一条语句:?


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左右。用: ?