MYSQL你们如何解决超多分页性能问题?

济南大飞哥 2019-05-13 11:05:21
阿里巴巴的Java开发手册有这么一个规则:

7. 【推荐】利用延迟关联或者子查询优化超多分页场景。
说明:MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回
N 行,那当 offset 特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过
特定阈值的页数进行 SQL 改写。
正例:先快速定位需要获取的 id 段,然后再关联:
SELECT a.* FROM 表 1 a, (select id from 表 1 where 条件 LIMIT 100000,20 ) b where a.id=b.id

她的思路是,先拿到所需id,然后回表拿到完整数据。
这里的关键就是子查询,如果拿到id的过程比较“费时”,那么sql的效率依然会比价低。我猜子查询这里应该尽量走覆盖索引。但是这里利用覆盖索引是比较难的。比如我们经常会使用时间段来查询数据,如果只在时间上建索引,那么要拿到id还是得回表,拿到id再回表一次拿到完整数据就得不偿失了。
我试了下通过建时间+id的组合索引,发现子查询的执行计划依然不是use index,而是use where;userindex,然后rows是个很大的值。所以,大家超多分页到底如何搞?

...全文
937 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
遇星 2019-05-17
  • 打赏
  • 举报
回复
你提到的那种分页方法,一般用的是表主键,百度一下延迟关联,很多这种优化案例
济南大飞哥 2019-05-17
  • 打赏
  • 举报
回复
引用 5 楼 受了伤风的星辰 的回复:
[quote=引用 4 楼 济南大飞哥 的回复:] [quote=引用 3 楼 受了伤风的星辰 的回复:] [quote=引用 2 楼 济南大飞哥 的回复:] [quote=引用 1 楼 受了伤风的星辰 的回复:] 如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。[/quote] 我的意思是,如果id是主键,为什么你建了时间字段的索引,还要回表?时间字段上的索引本身就包含主键id,根本不需要回表。 如果id不是主键,那么这个延迟关联就写错了,应该用主键来关联。[/quote] 不是组合索引,时间索引会包含主键信息?[/quote]
引用 4 楼 济南大飞哥 的回复:
[quote=引用 3 楼 受了伤风的星辰 的回复:] [quote=引用 2 楼 济南大飞哥 的回复:] [quote=引用 1 楼 受了伤风的星辰 的回复:] 如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。[/quote] 我的意思是,如果id是主键,为什么你建了时间字段的索引,还要回表?时间字段上的索引本身就包含主键id,根本不需要回表。 如果id不是主键,那么这个延迟关联就写错了,应该用主键来关联。[/quote] 不是组合索引,时间索引会包含主键信息?[/quote] MySQL的二级索引包含主键[/quote] 可以,不过我们按照阿里的规约建了一个sid主键(自增列),主要让mysql自己优化用。然后业务还有个业务主键,一般叫id,非主键。sid程序一般不用,都用id,不过我个人觉得sid可以用。
遇星 2019-05-17
  • 打赏
  • 举报
回复
引用 4 楼 济南大飞哥 的回复:
[quote=引用 3 楼 受了伤风的星辰 的回复:] [quote=引用 2 楼 济南大飞哥 的回复:] [quote=引用 1 楼 受了伤风的星辰 的回复:] 如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。[/quote] 我的意思是,如果id是主键,为什么你建了时间字段的索引,还要回表?时间字段上的索引本身就包含主键id,根本不需要回表。 如果id不是主键,那么这个延迟关联就写错了,应该用主键来关联。[/quote] 不是组合索引,时间索引会包含主键信息?[/quote]
引用 4 楼 济南大飞哥 的回复:
[quote=引用 3 楼 受了伤风的星辰 的回复:] [quote=引用 2 楼 济南大飞哥 的回复:] [quote=引用 1 楼 受了伤风的星辰 的回复:] 如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。[/quote] 我的意思是,如果id是主键,为什么你建了时间字段的索引,还要回表?时间字段上的索引本身就包含主键id,根本不需要回表。 如果id不是主键,那么这个延迟关联就写错了,应该用主键来关联。[/quote] 不是组合索引,时间索引会包含主键信息?[/quote] MySQL的二级索引包含主键
济南大飞哥 2019-05-17
  • 打赏
  • 举报
回复
引用 3 楼 受了伤风的星辰 的回复:
[quote=引用 2 楼 济南大飞哥 的回复:] [quote=引用 1 楼 受了伤风的星辰 的回复:] 如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。[/quote] 我的意思是,如果id是主键,为什么你建了时间字段的索引,还要回表?时间字段上的索引本身就包含主键id,根本不需要回表。 如果id不是主键,那么这个延迟关联就写错了,应该用主键来关联。[/quote] 不是组合索引,时间索引会包含主键信息?
遇星 2019-05-17
  • 打赏
  • 举报
回复
引用 2 楼 济南大飞哥 的回复:
[quote=引用 1 楼 受了伤风的星辰 的回复:] 如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。[/quote] 我的意思是,如果id是主键,为什么你建了时间字段的索引,还要回表?时间字段上的索引本身就包含主键id,根本不需要回表。 如果id不是主键,那么这个延迟关联就写错了,应该用主键来关联。
济南大飞哥 2019-05-17
  • 打赏
  • 举报
回复
引用 1 楼 受了伤风的星辰 的回复:
如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?
这当然可以,问题是组合索引建的合适,能让大部分查询id的走覆盖索引。
遇星 2019-05-14
  • 打赏
  • 举报
回复
如果id是主键,二级索引的内容是索引键+主键,为什么还要回表?

56,678

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧