前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql大量数据分页优化

mysql大量数据分页优化

作者头像
Java小咖秀
发布2020-07-03 15:11:31
2.4K0
发布2020-07-03 15:11:31
举报
文章被收录于专栏:Java冰冻三尺Java冰冻三尺

一般我们数据量大的时候,然后就需要进行分页,一般分页语句就是limit offset,rows。这种分页数据量小的时候是没啥影响的,一旦数据量越来越 大随着offset的变大,性能就会越来越差。下面我们就来实验下:

  1. 准备数据
    1. 建一个测试表引擎为MyISAM(插入数据没有事务提交,插入速度快)的表。
代码语言:javascript
复制
CREATE TABLE USER (
id INT ( 20 ) NOT NULL auto_increment,
NAME VARCHAR ( 20 ) NOT NULL,
address VARCHAR ( 20 ) NOT NULL,
PRIMARY KEY ( id ) 
) ENGINE = MyISAM;
  1. 写一个批量插入的存储过程
代码语言:javascript
复制
delimiter //
# 删除表数据
TRUNCATE TABLE t;
# 如果已经有sp_test_batch存储过程,将其删除,后面重新创建
DROP PROCEDURE IF EXISTS sp_test_batch;
# 创建存储过程,包含num和batch输入,num表示插入的总行数,batch表示每次插入的行数
CREATE PROCEDURE sp_test_batch(IN num INT,IN batch INT)
BEGIN
  SET @insert_value = '';
  # 已经插入的记录总行数
  SET @count = 0;
  # 
  SET @batch_count = 0;
  WHILE @count < num DO
    # 内while循环用于拼接INSERT INTO t VALUES (),(),(),...语句中VALUES后面部分
    WHILE (@batch_count < batch AND @count < num) DO
      IF @batch_count>0
      THEN 
        SET @insert_value = concat(@insert_value,',');
      END IF;
      SET @insert_value = concat(@insert_value,"('name", @count, "','address", @count, "')");
      SET @batch_count = @batch_count+1;  
    END WHILE;
 
    SET @count = @count + @batch_count;
    # 拼接SQL语句并执行
    SET @exesql = concat("insert into user(name,address) values ", @insert_value);  
    PREPARE stmt FROM @exesql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    # 重置变量值
    SET @insert_value = '';
    SET @batch_count=0;
  END WHILE;
  # 数据插入完成后,查看表中总记录数
  SELECT COUNT(id) FROM user;
END
CALL sp_test_batch(10000000,10000);

插入1000w数据

3.测试性能

下面我们分别针对于offset等于不同的值来进行实:offset等于10000时耗时

  • offset等于100000时耗时
  • offset等于1000000时耗时
  • offset等于5000000时耗时
  • offset等于10000000时耗时

从上图可以得出随着offset的值越大耗时就越来越多。这还只是1000w数据,如果我们上亿数据呢,可想而知这时候查询的效率有多差。下面我们来进行优化。

4 .进行优化

子查询的分页方式:

代码语言:javascript
复制
SELECT * FROM user WHERE  id >=  
(SELECT id FROM user  ORDER BY id LIMIT 9000000, 1) LIMIT 10

从图可以得出子查询确实速度快了一倍。

JOIN分页方式:

SELECT * FROM user t1 INNER join (SELECT id FROM user ORDER BY id LIMIT 9000000, 10) t2 on t2.id =t1.id

join的方式比子查询性能在稍微好点。

终极优化:

这个时间性能是最好的。这种优化必须要依赖前一次的查询的最大ID,如果是那种分页直接可以指定多少页的是不行的,必须是只能后一页,后一页这么点击。

代码语言:javascript
复制
SELECT id FROM user  where id > 9000000 ORDER BY id  LIMIT 10;

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA小咖秀 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档