数据库教程

mysql大数据分页查询性能优化

我的站长站 2022-03-29 人阅读

使用limit start, count分页语句

select * from product limit start, count

当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条), 如下:

select * from product limit 10, 20   0.016秒
select * from product limit 100, 20   0.016秒
select * from product limit 1000, 20   0.047秒
select * from product limit 10000, 20   0.094秒

我们已经看出随着起始记录的增加,时间也随着增大, 这说明分页语句limit跟起始页码是有很大关系的,那么我们把起始记录改为40w看下(也就是记录的一般左右)   

select * from product limit 400000, 20   3.229秒

再看我们取最后一页记录的时间

select * from product limit 866613, 20   37.44秒

难怪搜索引擎抓取我们页面的时候经常会报超时,像这种分页最大的页码页显然这种时间是无法忍受的。

从中我们也能总结出两件事情:
1)limit语句的查询时间与起始记录的位置成正比
2)mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用。

对limit分页问题的性能优化方法

利用表的覆盖索引来加速分页查询
我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引),那么这种情况会查询很快。
因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。
在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。现在让我们看看利用覆盖索引的查询效果如何:
这次我们之间查询最后一页的数据(利用覆盖索引,只包含id列),如下:

select id from product limit 866613, 20 0.2秒

相对于查询了所有列的37.44秒,提升了大概100多倍的速度
那么如果我们也要查询所有列,有两种方法,一种是id>=的形式,另一种就是利用join,看下实际情况:

SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20

查询时间为0.2秒,简直是一个质的飞跃。

另一种写法

SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id

查询时间也很短!

其实两者用的都是一个原理嘛,所以效果也差不多
Mysql的分页查询十分简单,但是当数据量大的时候一般的分页就吃不消了。
传统分页查询:

SELECT c1,c2,cn… FROM table LIMIT n,m

MySQL的limit工作原理就是先读取前面n条记录,然后抛弃前n条,读后面m条想要的,所以n越大,偏移量越大,性能就越差。

推荐分页查询方法

1、尽量给出查询的大致范围

SELECT c1,c2,cn... FROM table WHERE id>=20000 LIMIT 10;

2、子查询法

SELECT c1,c2,cn... FROM table WHERE id>=(SELECT id FROM table LIMIT 20000,1)LIMIT 10;

3、高性能MySQL一书中提到的只读索引方法

优化前SQL:

SELECT c1,c2,cn... FROM member ORDER BY last_active LIMIT 50,5

优化后SQL:

SELECT c1, c2, cn .. .
FROM member
INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5)
USING (member_id)

分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。

4、第一步用用程序读取出ID,然后再用IN方法读取所需记录
程序读ID:

SELECT id FROM table LIMIT 20000, 10;
SELECT c1, c2, cn .. . FROM table WHERE id IN (id1, id2, idn.. .)
相关推荐
  • mysql教程
  • sql查询
  • mysql大数据分页查询性能优化

    使用limit start, count分页语句select * from product limit start, count当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条), 如下:select * from product limit 10, 20 0.016秒select * from product ...

    数据库教程 130 2年前
  • 6天掌握mysql基础视频教程
    6天掌握mysql基础视频教程

    6天掌握mysql基础视频教程,生动形象,浅显易懂,清晰明了,以最新MySQL8为起点,了解MySQL8下各大特性,对于有数据库学习需求的朋友十分适合。以mysql客户端作为操作平台,原生SQL提供解决方案,深入理解SQL编...

    视频教程 100 4年前
  • Windows服务器IIS+PHP+MySQL安装配置教程

    服务器配置软件下载PHP(5.1.2):http://www.php.netMySQL(5.0.19):http://www.mysql.comZend Optimizer(2.6.2):http://www.zend.comphpMyAdmin(2.8.0.2):http://www.phpmyadmin.net假设 C: 为你现在所使用操作系统的系统盘,如果你目前操作系统不是安装在 C: ,请自...

    php教程 158 5年前
  • 查询重复数据,并且删除只保留一条SQL语法

    首先是SQL查询重复数据语法SELECT * FROM [表名] WHERE [字段] IN ( SELECT [字段] FROM [表名] GROUP BY [字段] HAVING COUNT([字段]) > 1);然后就是删除重复数据,只保留一条ID最小的数据DELETE FROM [表名] WHERE id IN ( SELECT * FROM ( ...

    数据库教程 42 1年前
  • sql查询统计字段重复次数语法

    查询 table_name 表中 field2 字段的值,并找出出现次数大于1的记录。同时,该查询还会显示 field1 字段的值和该字段对应的 field2 记录中的重复次数。SELECT field1, field2, COUNT(field2) FROM table_name GROUP BY field2 HAVING COUNT(field2)>1;...

    数据库教程 42 1年前
  • SQL新手入门SELECT数据库查询语句

    SELECT语义SELECT 语句用于从数据库中选取数据。结果被存储在一个结果表中,称为结果集。SELECT语法示例SELECT column_name,column_name FROM table_name;SELECT * FROM table_name;下面的 SQL 语句从 "Websites" 表中选取 "name" 和 "country" 列:SEL...

    数据库教程 129 4年前
最新更新