索引不只负责查找,还能避免排序、支持流式返回前几条结果。

order by 的第三种力量

use-the-index-luke 把 pipelined order by 称为索引的“第三力量”。它的价值不只是省掉排序,更在于:数据库可以不等全部结果准备好,就先返回最前面的若干行。

这对 Top-N 查询、消息列表、时间线与搜索结果页尤其关键。

group by 也可能受益

如果输入本身按分组键有序,数据库就可能避免额外排序,用接近流式的方式完成 group by。因此排序键、分组键与过滤键能否在一个索引里协同,非常值得在高频报表或列表页中提前设计。

offset 的问题

offset 的语义简单,但性能会随着页码变深而持续变差,因为数据库通常仍要先数过前面那些行。除此之外,它对并发插入也不稳定,容易出现“翻页漂移”。

Seek Pagination

更好的办法通常是 seek method:

  • 记住上一页最后一条记录的排序键;
  • 下一页直接用该键作为新的范围边界;
  • 让数据库借助索引从这个位置继续往后扫。

这本质上是把分页问题重新表达成一个索引擅长的范围查询问题。

排序必须可判定

稳定分页要求确定性排序。仅按非唯一列排序时,同值记录之间的先后并不稳定,因此通常要补一个唯一 tie-breaker,比如主键,并让索引顺序与 order by 保持一致。

一个实用提醒

如果你的列表页会不断翻到更深页面,优先思考“能否改成 seek pagination”,而不是先接受 offset 的线性退化。


来源:use-the-index-luke-sorting-and-grouping · use-the-index-luke-partial-results

相关页面:query-shape-and-index-usage · sql-execution-plans · sql-join-performance · sql-indexing