MySQL 索引详解:B+ 树、聚簇索引与最左前缀

MySQL 索引详解:B+ 树、聚簇索引与最左前缀

数据库原理里最绕的就是索引:B+ 树和 B 树什么区别?聚簇索引和二级索引差在哪?"最左前缀"到底怎么理解?联合索引字段顺序怎么排?这些概念拆开都懂,串起来就乱。这篇用一条主线------"一条 SQL 是怎么通过索引找到数据的"------把所有索引概念串起来。


一、结论先行

MySQL(InnoDB)索引的本质:一种把"全表扫描"变成"快速定位"的数据结构,底层是 B+ 树。 四个核心结论先记住:

  1. InnoDB 是聚簇索引组织表:表数据按主键的 B+ 树存放,主键索引的叶子节点直接存整行数据
  2. 二级索引的叶子存的是主键值,不是整行------查二级索引后要"回表"拿整行
  3. B+ 树碾压其他结构的原因:矮(层数少 = IO 少)+ 叶子有序且相连(范围查询友好)+ 非叶子只存 key(一页能塞更多索引,树更矮)
  4. 联合索引遵循最左前缀:字段顺序决定能命中哪些查询------排错顺序,索引白建

一句话:索引是拿空间换时间的"查字典目录",设计索引的本质是设计"查什么能走哪条目录、少翻几次书"。


二、类比理解:新华字典的两套查法

查一个生字,字典给了你两套方案:

字典设计 类比
拼音查字表 → 指向正文页码 → 翻到正文 二级索引:先查小目录,拿到主键(页码),再回正文取整行
部首查字法直接看正文区(正文按部首排列) 聚簇索引:正文本身就是按主键顺序排的,直接翻到那页就是整行

注意新华字典的细节:正文是按"部首/笔画"排的,不是按拼音排的------所以拼音查字表查完,还要"翻到正文那页"才能看到字的完整解释。

MySQL 完全一样:

  • 聚簇索引 = 正文:数据行按主键顺序存在 B+ 树叶子里,叶子就是数据本身
  • 二级索引 = 拼音表:叶子存的是"主键值"(像拼音表存页码),查到后要回正文(回表)取整行

再想 B+ 树为什么是"矮胖子":一棵存 1000 万行的 B+ 树,只要 3-4 层 ------因为每层能"扇出"几百上千个分支。磁盘 IO 一次读一层,3-4 次 IO 就能找到目标,而全表扫描要读 1000 万行。B+ 树是用"一次读多叉"换"极少的 IO 次数"。


三、深挖细节

3.1 B+ 树 vs B 树 vs 哈希:为什么是 B+ 树

结构 叶子是否存数据 范围查询 树高 结论
哈希 --- ❌ 只能等值(没有顺序) --- 只适合等值,如 Redis
B 树 非叶子也存数据 ❌ 中序遍历麻烦 更高(非叶子大,扇出小) 淘汰
B+ 树 只有叶子存数据,叶子间链表相连 ✅ 顺着链表扫 更矮(非叶子只存 key) InnoDB 用它

B+ 树两个碾压点:

  1. 非叶子节点不存数据,只存 key → 一个磁盘页(16KB)能塞的索引项远多于 B 树 → 树更矮 → IO 更少
  2. 叶子节点用链表串联且有序 → 范围查询(WHERE id BETWEEN 1 AND 100)找到起点后顺着链表扫,不用回上层反复遍历

3.2 聚簇索引 vs 二级索引:一次完整的查找

假设表:

sql 复制代码
CREATE TABLE user (
  id BIGINT PRIMARY KEY,        -- 聚簇索引(主键)
  name VARCHAR(20),
  phone VARCHAR(20),
  KEY idx_name (name)           -- 二级索引
);

执行 SELECT * FROM user WHERE name = '张三',MySQL 干了什么:
#mermaid-svg-M2Bu1yvJg2Aw1RZH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .error-icon{fill:#552222;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .marker.cross{stroke:#333333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH p{margin:0;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .cluster-label text{fill:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .cluster-label span{color:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .cluster-label span p{background-color:transparent;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .label text,#mermaid-svg-M2Bu1yvJg2Aw1RZH span{fill:#333;color:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .node rect,#mermaid-svg-M2Bu1yvJg2Aw1RZH .node circle,#mermaid-svg-M2Bu1yvJg2Aw1RZH .node ellipse,#mermaid-svg-M2Bu1yvJg2Aw1RZH .node polygon,#mermaid-svg-M2Bu1yvJg2Aw1RZH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .rough-node .label text,#mermaid-svg-M2Bu1yvJg2Aw1RZH .node .label text,#mermaid-svg-M2Bu1yvJg2Aw1RZH .image-shape .label,#mermaid-svg-M2Bu1yvJg2Aw1RZH .icon-shape .label{text-anchor:middle;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .rough-node .label,#mermaid-svg-M2Bu1yvJg2Aw1RZH .node .label,#mermaid-svg-M2Bu1yvJg2Aw1RZH .image-shape .label,#mermaid-svg-M2Bu1yvJg2Aw1RZH .icon-shape .label{text-align:center;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .node.clickable{cursor:pointer;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .arrowheadPath{fill:#333333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-M2Bu1yvJg2Aw1RZH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-M2Bu1yvJg2Aw1RZH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-M2Bu1yvJg2Aw1RZH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .cluster text{fill:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .cluster span{color:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-M2Bu1yvJg2Aw1RZH rect.text{fill:none;stroke-width:0;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .icon-shape,#mermaid-svg-M2Bu1yvJg2Aw1RZH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .icon-shape p,#mermaid-svg-M2Bu1yvJg2Aw1RZH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .icon-shape .label rect,#mermaid-svg-M2Bu1yvJg2Aw1RZH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-M2Bu1yvJg2Aw1RZH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-M2Bu1yvJg2Aw1RZH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-M2Bu1yvJg2Aw1RZH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} WHERE name=张三
走二级索引 idx_name 的 B+ 树
在叶子找到 张三 对应的主键 id
拿主键 id 回聚簇索引的 B+ 树再查一次
聚簇索引叶子直接取出整行数据

这就是"回表":二级索引查到的是主键,还要拿主键再走一遍聚簇索引才能拿到整行。两次 B+ 树查找。

怎么避免回表? 覆盖索引------要查的列都在二级索引里,就不用回表了:

sql 复制代码
-- name 和 phone 都在 idx_name 的"联合索引"里时,这个查询无需回表
SELECT name, phone FROM user WHERE name = '张三';

只要查询的列全在索引里,二级索引的叶子就够用了,直接"覆盖"。这是优化高频查询最实用的一招:把要查的列加进索引,让 SQL"在目录页就拿到答案,不用翻正文"。

3.3 联合索引与最左前缀

联合索引 KEY idx_name_phone (name, phone):先按 name 排,name 相同的再按 phone 排。

最左前缀规律:查询条件只要包含联合索引的"最左列"(或最左连续前缀),就能命中索引:

查询 是否走 idx_name_phone 原因
WHERE name = '张三' ✅ 走 包含最左列 name
WHERE name = '张三' AND phone = '138...' ✅ 走 完整前缀
WHERE phone = '138...' ❌ 不走 没有 name,无法从最左开始匹配
WHERE name LIKE '张%' ✅ 走 前缀匹配(范围)
WHERE name LIKE '%三' ❌ 不走 后缀匹配无法定位起点

为什么? 索引的顺序是字典式的:先按第一列排。你只知道第二列的值,等于"只知道姓但不知道名还去查电话本按名排序的区"------没法定位。

3.4 联合索引字段顺序怎么排

顺序错了索引就废了一半,三条原则:

  1. 区分度高的放前面 (选择性):gender(男女二值,区分度低)放前面会先筛出一半,浪费;email(几乎全唯一)放前面直接定位
  2. 最常单独查的字段放最左 :如果 name 经常单独 WHERE name = ?,name 必须放最左,否则单独查走不了索引
  3. 查询最频繁的组合优先(a, b) 建了,a 单独查也能走,就不要再单独建 a 的索引(覆盖)

3.5 索引失效的经典场景

场景 为什么失效 示例
隐式类型转换 字段是 varchar,条件传数字,MySQL 对字段做函数转换 WHERE phone = 138...(phone 是 varchar)
对索引列用函数 函数破坏了有序性 WHERE YEAR(create_time) = 2024
like '%xx' 后缀匹配找不到起点 WHERE name LIKE '%三'
or 条件含非索引列 有一路要走全表,优化器干脆全表 WHERE name = 'a' OR age = 18(age 无索引)

联合索引注意WHERE name = '张三' AND phone = '138...' 走最左没问题;但 WHERE phone = '138...' 单独查就失效------这就是"联合索引字段顺序"重要的原因。

3.6 Explain 怎么看

排查 SQL 性能,EXPLAIN SELECT ... 看四列就够:

看什么 好坏
type 访问类型 const/eq_ref 最好,ref 好,range 可接受,ALL = 全表扫描要优化
key 实际用的索引 为 NULL = 没走索引
rows 预估扫描行数 越小越好
Extra 附加信息 出现 Using filesort(排序没用索引)、Using temporary(临时表)要警惕

四、梳理成一个知识点

#mermaid-svg-KgXbSIhzzwL4mD8Z{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KgXbSIhzzwL4mD8Z .error-icon{fill:#552222;}#mermaid-svg-KgXbSIhzzwL4mD8Z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KgXbSIhzzwL4mD8Z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .marker.cross{stroke:#333333;}#mermaid-svg-KgXbSIhzzwL4mD8Z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KgXbSIhzzwL4mD8Z p{margin:0;}#mermaid-svg-KgXbSIhzzwL4mD8Z .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .cluster-label text{fill:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .cluster-label span{color:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .cluster-label span p{background-color:transparent;}#mermaid-svg-KgXbSIhzzwL4mD8Z .label text,#mermaid-svg-KgXbSIhzzwL4mD8Z span{fill:#333;color:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .node rect,#mermaid-svg-KgXbSIhzzwL4mD8Z .node circle,#mermaid-svg-KgXbSIhzzwL4mD8Z .node ellipse,#mermaid-svg-KgXbSIhzzwL4mD8Z .node polygon,#mermaid-svg-KgXbSIhzzwL4mD8Z .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .rough-node .label text,#mermaid-svg-KgXbSIhzzwL4mD8Z .node .label text,#mermaid-svg-KgXbSIhzzwL4mD8Z .image-shape .label,#mermaid-svg-KgXbSIhzzwL4mD8Z .icon-shape .label{text-anchor:middle;}#mermaid-svg-KgXbSIhzzwL4mD8Z .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .rough-node .label,#mermaid-svg-KgXbSIhzzwL4mD8Z .node .label,#mermaid-svg-KgXbSIhzzwL4mD8Z .image-shape .label,#mermaid-svg-KgXbSIhzzwL4mD8Z .icon-shape .label{text-align:center;}#mermaid-svg-KgXbSIhzzwL4mD8Z .node.clickable{cursor:pointer;}#mermaid-svg-KgXbSIhzzwL4mD8Z .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .arrowheadPath{fill:#333333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KgXbSIhzzwL4mD8Z .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KgXbSIhzzwL4mD8Z .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KgXbSIhzzwL4mD8Z .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KgXbSIhzzwL4mD8Z .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .cluster text{fill:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z .cluster span{color:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KgXbSIhzzwL4mD8Z .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KgXbSIhzzwL4mD8Z rect.text{fill:none;stroke-width:0;}#mermaid-svg-KgXbSIhzzwL4mD8Z .icon-shape,#mermaid-svg-KgXbSIhzzwL4mD8Z .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KgXbSIhzzwL4mD8Z .icon-shape p,#mermaid-svg-KgXbSIhzzwL4mD8Z .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KgXbSIhzzwL4mD8Z .icon-shape .label rect,#mermaid-svg-KgXbSIhzzwL4mD8Z .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KgXbSIhzzwL4mD8Z .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KgXbSIhzzwL4mD8Z .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KgXbSIhzzwL4mD8Z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 索引 = B+树
聚簇: 叶子存整行
二级: 叶子存主键
回表拿整行
覆盖索引免回表
联合索引 最左前缀
字段排: 区分度高在前
失效场景: 函数/隐式转换/like%x

知识点:MySQL 索引 = B+ 树(矮胖 + 叶子链表)= 少量 IO 定位数据。聚簇索引叶子存整行,二级索引叶子存主键要回表,把查询列塞进索引(覆盖索引)就能免回表。联合索引必须满足最左前缀,字段顺序按"区分度高 + 常单查的放最左"排;函数、隐式类型转换、后缀 like 会让索引失效。性能排查用 Explain 盯 type/key/rows。

口诀:聚簇存行二存键,回表一次变两次;覆盖索引免回表,最左前缀定生死;区分度高放前面,函数转换毁索引。


追问链

追问 1:"B+ 树到底比平衡二叉树强在哪?"

→ 强在"矮"和"顺序"。平衡二叉树每个节点只能分两个叉,树高是 log₂N(1000 万行要 24 层);B+ 树每个节点能分几百个叉,3-4 层。磁盘 IO 一次读一层,24 次 IO vs 4 次 IO,高下立判。叶子链表则让范围查询不用中序遍历。

追问 2:"为什么不建议用 UUID 当主键?"

→ 聚簇索引的数据按主键物理顺序排。UUID 无序,插入时数据要频繁移动/页分裂,写性能差还产生碎片。自增主键保证插入总在末尾,顺序写性能最好。业务不暴露自增 id 用"雪花 id"(趋势递增),也不要用随机 UUID 当主键。

追问 3:"回表一定比全表快吗?"

→ 不一定。回表是随机 IO(每次拿主键去聚簇索引跳着读)。当二级索引筛选出的行数占比很大(比如查出了 30% 的行),回表 30% 行可能比全表顺序扫描还慢------优化器可能直接选全表扫(type=ALL)。这就是为什么"区分度低"的列不适合单独建索引。

追问 4:"索引越多越好吗?"

→ 不是。每建一个索引,写入(INSERT/UPDATE/DELETE)都要同步维护这棵树 ,索引越多写越慢;每个索引还占磁盘空间。实践原则:只为高频查询建索引,能用联合索引覆盖的别建多个单列索引

追问 5:"最左前缀里,范围查询后面的字段还用得上吗?"

→ 用不上(或部分用不上)。WHERE name > '张' AND phone = '138':name 范围定位后,phone 的等值条件无法继续用索引过滤 (因为范围后面的列不再有序),只能回表后再过滤。所以联合索引设计时,把等值查询的列放前面,范围查询的列放后面

总结

InnoDB 索引 = B+ 树,聚簇索引叶子存整行(表数据按主键排),二级索引叶子存主键值需回表,覆盖索引把查询列塞进二级索引免回表。联合索引走最左前缀,字段顺序按区分度高 + 等值列放前;函数、隐式转换、后缀 like 让索引失效。Explain 看 type 是否 ALL、key 是否为空。

Agent 的记忆、会话、用户数据最终都落在 MySQL------理解了聚簇索引和覆盖索引,你就知道为什么 Agent 的会话查询要设计好主键和索引,而不是无脑全表扫。下一篇讲缓存层:Redis 分布式锁为什么这么多坑。

相关推荐
萧瑟余晖1 小时前
Java深入解析篇五十四之对象模型详解
java·开发语言
张文是假的啊1 小时前
Java | record | Controller逻辑
java·开发语言
勿忘,瞬间1 小时前
Mybatis高阶
java·数据库·mybatis
运维行者_2 小时前
ISP 企业级带宽计费怎么做?网络流量计费的 6 大核心能力
运维·服务器·网络·数据库·支持向量机·接口隔离原则
奇树谦2 小时前
PCB生产制造全流程详解:从开料、钻孔、沉铜到检测、包装
网络·数据库·制造
驾驭人生2 小时前
Hangfire.Redis.StackExchange 已归档停更!生产任务卡死、重复执行、网络抖动问题解决方案
数据库·redis·缓存
xierui1231232 小时前
Agent记忆不是聊天记录:用三层存储构建可追溯的 AI 工作流
数据库·人工智能·aigc·软件工程
2301_800074213 小时前
mysql DQL
数据库·sql·mysql
嘻哈baby3 小时前
Go 函数中的参数为什么不支持默认值?
java·开发语言·jvm