之前上次在部门的分享会上,听了关于MySQL大数据的分页,即怎样使用limit offset,N来进行大数据的分页,现在做一个记录:
首先我们知道,limit offset,N的时候,MySQL的查询效率特别的低,注意是在limit大数据量的时候,测试的表的数据量是1KW条,limit 5000000,N的时候,速度变的非常的慢,当然了offset特别小的时候,查询的速度没有什么差别。那我们来想一下什么没原因造成的?
那其实原因就是MySQL并不是跳过offset行,然后单取N行,而是取offset+N行,然后返回放弃前offset行,返回N行,所以这样的话,查询的效率就特别的低,那当offset特别大的时候,效率就非常的低下。
优化的办法:
1.我们从业务的逻辑上进行解决,比如说不允许翻页超过100页,比如百度的分页才只有79页,所以我们没有必要去分那么多的页,这个是从业务的逻辑上来进行控制的。
2.我们可以试着不用limit进行查询数据。
我们来看一下用了offset和不用offset两者的一个对比:
mysql> select id,name from logs limit 5000000,10; +---------+--------------------------------------------+ | id | name | +---------+--------------------------------------------+ | 5554609 | 新闻 | .................. | 5554618 | 股票信息 | +---------+--------------------------------------------+ 10 rows in set (5.33 sec) mysql> select id,name from logs where id>5000000 limit 10; +---------+--------------------------------------------------------+ | id | name | +---------+--------------------------------------------------------+ | 5000001 | 互联网金融 | ................. | 5000002 | P2P理财 | +---------+--------------------------------------------------------+ 10 rows in set (0.00 sec)
那么我们明显的观察到两者的时间差了整整的5倍多。
但我们同时也发现,2次查询的结果是不一样的,那这是因为我们的数据中间有被物理删除过,数据出现了空洞。
解决的方法就是:数据我们一般不进行物理删除,我们可以进行逻辑删除,最终在页面上显示数据的时候,逻辑删除的条目不显示即可。(一般来说,大网站的数据都是不物理删除的,只做逻辑删除)
那我们再想一种比较极端的思路,如果我们非要物理删除数据,还不限制用户进行分页,那怎么办?
那我们尽量的只查有索引的ID,通过索引查出来的id,速度非常的快,然后我们再根据查出来的id,进行回行一次性的取具体的数据。这就是延迟索引。