标准答案

  1. 索引 (a, b, c) 能有效支持 a、a+b、a+b+c 的连续前缀条件,跳过 a 直接按 b 查询通常无法高效定位。
  2. 常见原则是把稳定的等值过滤列放前面,再考虑范围列与排序列,具体顺序必须结合查询模式。
  3. 高选择性不总是必须第一位;如果每个查询都先按 tenant_id 限定,tenant_id 放在前面能先划定正确的数据域。
  4. 范围条件之后的列往往难以同时承担精确过滤或全局排序,需要通过执行计划验证。
  5. 一个索引服务一组相近查询,不要期待一个巨型联合索引同时覆盖所有页面。

题目解析

最左前缀不是机械规则,而是 B+ 树排序方式的结果。索引按 a 排序,a 相同的再按 b 排序;没有 a 的值时,b 在整棵树中并不连续,因此无法直接定位一个小区间。

字段顺序应先收集典型 SQL。比如订单列表总是 tenant_id 等值、status 等值、created_at 倒序,那么 (tenant_id, status, created_at) 很可能有价值;若 status 选择性极低,也要检验它是否真能缩小扫描范围。

代码示例

下面的索引与查询让租户和状态先定位,再按创建时间倒序读取最近订单。

sql
CREATE INDEX idx_orders_tenant_status_created
  ON orders (tenant_id, status, created_at DESC);

SELECT id, created_at
FROM orders
WHERE tenant_id = ? AND status = ?
ORDER BY created_at DESC
LIMIT 20;

常见误区

  • 只按单列基数排序索引字段,忽略租户边界和实际等值条件。
  • 把范围列放在前面后仍期待后面的列完整用于排序或过滤。

作者信息