在当今数据驱动的时代,MySQL 作为一款广泛使用的关系型数据库,分页查询功能是我们日常开发中经常用到的操作。然而,你是否注意到随着分页数量的增加,查询耗时也在急剧上升?这不仅影响用户体验,还可能成为系统性能的瓶颈。今天,就让我们一起深入探究 MySQL 分页的奥秘,学习如何优化分页查询,让你的数据库查询如闪电般快速!💥
一、常见分页方式与问题:揭开性能瓶颈的面纱🎯
(一)传统分页查询的“痛点”
通常,我们使用 ORDER BY LIMIT start, offset 的方式进行分页查询,例如:
1
SELECT*FROM `t1` WHERE ftype=1ORDERBY id DESC LIMIT 100, 10;
yejr@imysql.com> EXPLAIN SELECT*FROM (SELECT*FROM `t1` WHERE id > ( SELECT id FROM `t1` WHERE ftype=1ORDERBY id DESC LIMIT 935510, 1) LIMIT 10) t ORDERBY id DESC\G ***************************1.row*************************** id: 1 select_type: PRIMARY table: <derived2> type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 10 Extra: Using filesort ***************************2.row*************************** id: 2 select_type: DERIVED table: t1 type: ALL possible_keys: PRIMARY key: NULL key_len: NULL ref: NULL rows: 973192 Extra: Usingwhere ***************************3.row*************************** id: 3 select_type: SUBQUERY table: t1 type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 935511 Extra: Usingwhere
性能提升效果
1 2 3 4
yejr@imysql.com>SELECT*FROM (SELECT*FROM `t1` WHERE id > ( SELECT id FROM `t1` WHERE ftype=1ORDERBY id DESC LIMIT 935510, 1) LIMIT 10) T ORDERBY id DESC; … rowsinset (1.86 sec) # 采用子查询优化,从 profiling 的结果来看,相比原来的那个 SQL 快了:28.2%
(三)INNER JOIN 优化法
优化策略阐述
采用 INNER JOIN 优化,JOIN 子句里优先从索引获取 ID 列表,然后直接关联查询获得最终结果,这里不需要加 10。
yejr@imysql.com> EXPLAIN SELECT*FROM (SELECT*FROM `t1` WHERE id > ( SELECT id FROM `t1` ORDERBY id DESC LIMIT 935510, 1) LIMIT 10) t ORDERBY id DESC; ***************************1.row*************************** id: 1 select_type: PRIMARY table: <derived2> type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 10 Extra: Using filesort ***************************2.row*************************** id: 2 select_type: DERIVED table: t1 type: ALL possible_keys: PRIMARY key: NULL key_len: NULL ref: NULL rows: 973192 Extra: Usingwhere ***************************3.row*************************** id: 3 select_type: SUBQUERY table: t1 type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 935511 Extra: Using index
1 2 3 4
yejr@imysql.com>SELECT*FROM (SELECT*FROM `t1` WHERE id > ( SELECT id from `t1` ORDERBY id DESC LIMIT 935510, 1) LIMIT 10) t ORDERBY id DESC; … 10rowsinset (2.01 sec) # 采用子查询优化,从 profiling 的结果来看,相比原来的那个 SQL 快了:10.6%