MySQL分页优化实测效果明显.docxVIP

  • 2
  • 0
  • 约6.77千字
  • 约 8页
  • 2019-04-18 发布于江苏
  • 举报
MySQL 分页优化 通常,我们会采用 ORDER BY LIMIT start, offset 的方式来进行分页查询。例如下面这个 SQL : SELECT * FROM `t1` WHERE ftype=1 ORDER BY id DESC LIMIT 100, 10; 或者像下面这个不带任何条件的分页 SQL : SELECT * FROM `t1` ORDER BY id DESC LIMIT 100, 10; 一般而言,分页 SQL 的耗时随着 start 值的增加而急剧增加,我们来看下面这 2 个不同起 始值的分页 SQL 执行耗时: yejr@ SELECT * FROM`t1` WHEREftype=1 ORDERBY id DESC LIMIT 500, 10; ? 10 rows in set (0.05 sec) yejr@ SELECT * FROM`t1` WHEREftype=6 ORDERBY id DESC LIMIT 935500, 10; ? 10 rows in set (2.39 sec) 可以看到,随着分页数量的增加, SQL 查询耗时也有数十倍增加,显然不科学。今天我们 就来分析下,如何能优化这个分页方案。 一般滴,想要优化分页的终极方案就是:没有分 页,哈哈哈 ~~~ ,不要说我讲废话,确实如此,可以把分页算法交给 Sphinx 、 Lucence 等 第三方解决方案,没必要让 MySQL 来做它不擅长的事情。 当然了,有小伙伴说,用第三方太麻烦了,我们就想用 MySQL 来做这个分页,咋办呢?莫急,且待我们慢慢分析,先看 下表 DDL 、数据量、查询 SQL 的执行计划等信息: yejr@ SHOW CREATE TABLE `t1`; CREATE TABLE `t1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, ... `ftype` tinyint(3) unsigned NOT NULL, ... PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; yejr@ select count(*) from t1; +----------+ | count(*) | +----------+ | 994584 | +----------+ yejr@ EXPLAIN SELECT * FROM `t1` WHERE ftype=1 ORDER BY id DESC LIMIT 500, 10\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 510 Extra: Using where yejr@ EXPLAIN SELECT * FROM `t1` WHERE ftype=1 ORDER BY id DESC LIMIT 935500, 10\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 935510 Extra: Using where 可以看到,虽然通过主键索引进行扫描了,但第二个 SQL 需要扫描的记录数太大了,而且 需要先扫描约 935510 条记录, 然后再根据排序结果取 10 条记录, 这肯定是非常慢了。 针 对这种情况,我们的优化思路就比较清晰了,有两点: 1、尽可能从索引中直接获取数据,避免或减少直接扫描行数据的频率 2、尽可能减少扫描的记录数,也就是先确定起始的范围,再往后取 N 条记录即可 据此,我们有两种相应的改写方法:子查询、表连接,即下面这样的: #采用子查询的方式优化,在子查询里先从索引获取到最大 id ,然后倒序排,再取 10 行结果集 #注意这里采用了 2 次倒序排,因此在取 LIMIT 的 start 值时,比原来的值加了 10 ,即 935510 ,否则结果将和原来的不一致 yejr@ EXPLAIN SELECT * FROM (SELECT * FROM `t1` WHERE id ( SELECT id FROM `t1` WH

文档评论(0)

1亿VIP精品文档

相关文档