跳到正文

SQL、索引与执行计划 ​

  • 状态:未准备
  • 适用方向:共用 / Go 后端重点
  • 最近复习:待填写
  • 下次复习:待安排

一句话回答 ​

索引以额外空间和写入成本换取特定访问路径的效率;优化从真实 SQL、数据分布和执行计划出发,而不是见到 WHERE 就加索引。

原理解释 ​

以 MySQL 8.x InnoDB 为例,常见索引使用 B+ 树;聚簇索引叶子保存行数据,二级索引叶子携带主键。二级索引找到主键后可能需要回表;覆盖索引能从索引取得本次查询所需列,但也增加维护成本。

联合索引 (conversation_id, created_at, id) 按元组顺序排列,适合按会话筛选再按时间与 ID 排序。最左前缀描述有效访问方式,不等于遗漏首列永远不能使用索引;优化器可能选全索引扫描等路径,应看实际计划。

sql
SELECT id, created_at
FROM messages
WHERE conversation_id = ?
  AND (created_at < ? OR (created_at = ? AND id < ?))
ORDER BY created_at DESC, id DESC
LIMIT 20;

以上为假设表结构的游标分页例子,参数由驱动绑定。稳定唯一的排序组合避免同时间记录跳漏;是否有效利用联合索引仍需用实际数据验证。深 OFFSET 常需扫描并丢弃许多行,游标分页则不适合任意跳页。

场景与边界 ​

函数包裹列、隐式转换、前导通配符等可能妨碍有效范围查找,但不能一概说“索引完全失效”。EXPLAIN 看访问方式、选中索引、估计行数和额外排序;支持的版本可用 EXPLAIN ANALYZE 对照实际执行,注意它会执行查询。小表或低选择性条件可能全表扫描更划算。

项目中的应用 ​

沿 EinoTalk MySQL 访问核对消息历史查询、表结构和索引;上述列名只是教学假设,不代表项目现有 schema。

常见追问 ​

  • 索引越多越好? 占空间并增加插入、更新、删除成本。
  • 唯一索引只加速吗? 还提供数据库层并发唯一性约束,适合业务去重。
  • SELECT * 为什么要谨慎? 增加传输和解码成本,也可能失去覆盖访问机会。

参考资料 ​

理解机制,讲清取舍,用复盘检验掌握。