首先我们先创建个数据表做测试
表名 test (id(int) , name(var char) , content(text) , pid(int) ) 往里面倒几百万条数据进去做测试。

我们都知道分页是 这样写的

select * from test limit 10,20;

比如每页显示perpage条,当前是第N页;

那么就是这么来写

select * from test limit ( N-1 )*perage,N
1
好我们现在先来试试查询速度

select id,name from test limit 1000,10;
1
先从一千页分起; 一千行还看不出什么基本上0.01秒就可以了,

select id,name from collect test 1000000,10;
1
从100万行来分 现在问题就来了 要差不多10秒左右了; 这是哪里出了问题?

其实很简单 因为它是要先找出前的100万行 再取出10行 ,所以速度会慢 。

今天我们就要来讲解一下这个问题我们要怎么解决

我们要知道公司的需求 从业务上来解决 我下面写几个优化方案、

1、模仿百度、谷歌方案

类似于分段。我们给每次只能翻100页、超过一百页的需要重新加载后面的100页。这样就解决了每次加载数量数据大 速度慢的问题了

2、记录每次取出后的最大id 然后 where id = 最大id limit 10;这样就可以解决了 然后我们来跑一下;

select id from test where id = 最大id limit 10;看看结果,时间是0.001秒! 几乎可以说是没有任何时间了

3、做索引

先看看没做索引之前的加载速度

select * from test where pid=1 order by id limit 1000000,10;

很慢,用了十多秒呢!

是不是很纳闷是怎么回事呢 因为我们这个pid 做了全局扫描啊 pid一个个对比过来那可是耗费了非常多的时间;下面我们看看要怎么来添加索引做优化

建一个索引表:p(id,name,pid) 并设置成定长,然后做分页,分页出结果再到 test 里面去找name。

select * from p where pid=1 order by id limit 1000000,10 ;
1
还是有点慢。基本上 4 - 5秒可以跑完。

其实这个我给大家买了个关子 我是建立三个列(id,name,pid) *这里重点注意下* 列越多越慢 因为他要一直回行(意思就是他要每次都要找出这个字段的内容。然后对比了where发现这个name取出来没有用 又把它丢了重新取 每次都要多取一个name ) 要是在我们正常开发中 可能有七八个列甚至更多的试试这个是致命的 所以最好是 只建立 id 和 pid 然后查出10个pid 取出id 单独去查出来 或者是子查询 有会比较快 。但是如果数据量小的话就不推荐了 因为我这说的是百万级别的查询了 。这样查询大概可以翻个一番了;

再测试: select id from test where pid = 1 limit 100000,10; 0.1秒这样就非常快了 记住pid是索引所以找个id还是非常快的。

得出结论:如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!

这样就完美解决了分页问题了。可以快速返回id就有希望优化limit , 按这样的逻辑,百万级的limit 应该在0.0x秒就可以分完。

posted on 2019-05-17 20:20  骑猪南下L  阅读(440)  评论(0编辑  收藏  举报