本文共 2266 字,大约阅读时间需要 7 分钟。
在实际应用中,使用select * limit offset, rows
进行深度分页时,可能会面临性能瓶颈,特别是在数据量较大的情况下。这时候,我们需要采取一些优化策略来提升查询效率。以下是一些常用的优化方法和实际案例分析。
类似于前端分页的做法,每次只加载一定数量的数据(如100页),而不是一次性加载大量数据。这样可以减少后端处理的负担,提升性能。
示例:
where
语句筛选这种方法适用于有主键ID的情况。通过记录每次查询的最大ID,可以快速获取下一批数据。
示例:
select * from table where id > 最大id limit 10000, 10
最大id
是前一次查询的最大值。IN
获取ID列表通过IN
子句获取满足条件的ID列表,再进行批量查询。
示例:
select * from table where id in (select id from table where user = 'xxx') limit 10000, 10
join
方式 + 覆盖索引(推荐)这种方法结合了join
和覆盖索引,适用于需要同时满足where
和limit
条件的情况。
示例:
select * from table inner join (select id from table where user = 'xxx' limit 10000, 10) b using (id)
这种方法适用于需要根据主键分块查询的情况。通过分块查询,可以减少每次查询的数据量,提升性能。
步骤:
select count(1) as countAllNumber from test_table
countAllNumber / 4 = 50
select id from test_table where id > 0 limit 50, 1
select id from test_table where id > 51 limit 50, 1
优点:
jdbcpagingReader
和db索引分区器
jdbcpagingReader
使用方式:
public static String generateLimitSqlQuery(AbstractSqlPagingQueryProvider provider, boolean remainingPageQuery, String limitClause) { StringBuilder sql = new StringBuilder(); sql.append("SELECT ").append(provider.getSelectClause()); sql.append(" FROM ").append(provider.getFromClause()); buildWhereClause(provider, remainingPageQuery, sql); buildGroupByClause(provider, sql); sql.append(" ORDER BY ").append(buildSortClause(provider)); sql.append(" ").append(limitClause); return sql.toString();}
limitClause
默认为limit 10
,每次查询10条记录。db索引分区器
使用方式:
test_table
)id
)id
)分块查询步骤:
select count(1) as countAllNumber from test_table
countAllNumber / 4 = 50
select id from test_table where id > 0 limit 50, 1
select id from test_table where id > 51 limit 50, 1
拼接查询SQL:
select id from test_table where id > 0 and id < 51 order by id
通过以上方法,可以有效提升MySQL深度分页的性能。选择合适的方法取决于具体的业务需求和数据结构。无论是前端控制、记录最大ID、使用IN
子句、join
方式,还是db索引分区器
,都可以根据实际情况进行优化。
转载地址:http://nfbfk.baihongyu.com/