欢迎光临
我们一直在努力

数据库 mysql 八股 3

🥰个人主页:会编程的土豆(欢迎来访) 💎作者简介:后端学习者 ❄️个人专栏:数据结构与算法,数据库,leetcode ✨那些你一个人走过的夜路,终将化作照亮未来的光

一、索引是什么

1. 一句话定义

索引 = 给表做的「目录」。

  • 有索引:常能少扫很多行
  • 没索引:可能整表翻(全表扫描)

2. 为什么需要索引

表里有 100 万用户,你要查:

SELECT * FROM users WHERE phone = '13800001111';

要点:

  • 索引不是让 SQL 语法变厉害
  • 而是让「找数据」这条路更短

3. 在整条 SQL 链路里的位置

你发一条 SQL
→ 优化器要想:有没有合适索引?走哪个最快?
→ 执行器按计划去取数
→ 存储引擎(InnoDB)里,索引和数据真正怎么组织


二、主键索引与普通索引

1. 主键索引(最常见)

每张表通常有一个主键(如 id)。

在 InnoDB 里可以先这么理解:

  • 主键像主目录
  • 数据行跟着主键这套结构放着

所以:

SELECT * FROM newtable WHERE id = 3;

一般会很快——因为常常直接走主键。


2. 普通索引(二级索引)

经常按姓名查时,可以给 name 建索引:

— 概念:给 name 建目录
CREATE INDEX idx_name ON newtable(name);

查询:

SELECT * FROM newtable WHERE name = '炎龙铠甲';

直觉过程(两步)

  • 先在 name 目录里找到对应位置
  • 拿到主键 id,再根据主键把整行数据取出来
  • 第 2 步叫「回表」:普通索引有时要多跳一次。


    3. 索引不是越多越好

    先够用的原则

  • 常作为查询条件的列,才考虑加(WHERE / JOIN 常用字段)
  • 主键本身已是索引,不必重复纠结
  • 别给所有列都建索引

  • 4. 什么样的条件更容易用上索引

    比较容易

    WHERE id = 3
    WHERE phone = '138…'
    WHERE name = '张三'

     比较容易废掉或不好用(先混个脸)

    WHERE age + 1 = 20 — 对列做运算
    WHERE name LIKE '%铠甲' — 前模糊
    WHERE name != '张三' — 不等有时也不友好

    零基础先记:

    等值查、条件干净,更容易走索引。


    5. 自己怎么看有没有走索引

    EXPLAIN SELECT * FROM newtable WHERE id = 3;

    先看:

    • type:访问方式粗不粗
    • key:实际用了哪个索引

    有用到索引时,常能看到索引名;全表扫则会比较「笨」。


    三、回表

    1. 普通索引怎么查(引出回表)

    表 newtable:主键 id,普通索引在 name 上。

    SELECT * FROM newtable WHERE name = '炎龙铠甲';

    两步直觉

  • 先在 name 目录里找到「炎龙铠甲」→ 拿到对应的 id
  • 再拿着这个 id,去主键/数据那本「主书」里把整行取出来(id、name、age…)
  • 定义

    回表 = 从「普通索引」跳回「主键那套数据」再取完整行。

    像:目录上只有页码,还得翻回正文把整页看完。


    2. 为什么要回表?

    普通索引里通常不存整行所有字段,主要存:

    • 索引列的值(如 name)
    • 对应的主键(id)

    你要的是 SELECT *(所有列),目录里不够,就必须回主书再拿。


    四、覆盖索引

    1. 一句话定义

    覆盖索引 = 这次查询需要的列,索引里全有了,够用,不必再回主表。


    2. 例子

    只要姓名:

    SELECT name FROM newtable WHERE name = '炎龙铠甲';

    此时:

    • 在 name 索引里已经能拿到 name
    • 主键 id 通常也在索引里
    • 若你要的列都被索引「盖住」→ 不用回表

    像:目录上已经写了你要的信息,不用再翻正文。


    3. 对比记忆

    查询常是否回表原因
    SELECT * … WHERE name = ? 常常要 * 要整行,普通索引不够
    SELECT name … WHERE name = ? 常常不要 更容易被索引覆盖
    SELECT * … WHERE id = ? 一般直接拿 主键对着整行

    实用提醒: 少用盲目的 SELECT *,只查需要的列,更容易吃到覆盖索引。


    五、联合索引 & 最左前缀

    1. 联合索引是什么

    联合索引 = 一个目录同时按多列排序(例如先 name,再 age)。

    不是建两个索引,而是一本合订目录。

    CREATE INDEX idx_name_age ON newtable(name, age);

    意思:目录按 (name, age) 这个顺序排。


    2. 为什么要用联合索引?

    假如你经常这样查:

    WHERE name = '炎龙铠甲' AND age = 89

    先记感觉:

    经常一起出现在 WHERE 里的列,可以考虑做成联合索引。


    3. 最左前缀(核心)

    联合索引 (name, age) 可以想成:

    先按 name 排成大组
    └── 同一 name 里,再按 age 排

    所以它最认:从左边第一列开始用。

     容易用上

    WHERE name = '炎龙铠甲'
    WHERE name = '炎龙铠甲' AND age = 89

    • 只用到最左的 name → 可以
    • name + age 都用到 → 更理想

     错误用法(用不好)

    WHERE age = 89

    只有 age,跳过了最左边的 name → 这本合订目录不好使。

    像新华字典:不按拼音首字母,却按页脚小字找。

    口诀:

    联合索引:从左往右用;中间不能空着跳。


    4. 和覆盖索引的关系

    如果索引是 (name, age),你查:

    SELECT name, age FROM newtable WHERE name = '炎龙铠甲';

    需要的列目录里都有 → 更容易变成覆盖索引,少回表。


    5. 字段顺序怎么选(实用原则)

    建 (a, b, c) 时,大致想:

  • 区分度高、常出现在等值查询里的,更靠左(如手机号、用户 id)
  • 经常一起查的组合,按「最左前缀能覆盖最多语句」来排
  • 只按右边列查、几乎从不按左边列查 → 这个联合索引可能建歪了
  • 例子

    • 常查 WHERE name = ? 或 name + age → (name, age) 合理
    • 几乎只查 WHERE age = ? → 单独给 age 建索引,别指望 (name, age) 救你

    六、EXPLAIN 速查(配套工具)

    1. 怎么用

    EXPLAIN SELECT * FROM newtable WHERE id = 3;

    2. 零基础先看三列

    列看什么
    type 访问方式好不好(ALL 最要警惕)
    key 实际用了哪个索引(NULL 很危险)
    rows 大概扫描多少行(越小通常越好)

    3. 口诀

    EXPLAIN 先问路;type 看姿势,key 看索引用没,rows 看翻多少;遇见 ALL,心里敲锣。


    七、总复习口诀

    主题一句话
    索引 表的目录,让查找更快
    主键索引 主目录,常直接对着整行
    普通索引 先找主键,再回表取整行
    回表 从二级索引跳回主数据
    覆盖索引 目录里字段已够,不用回表
    联合索引 多列合订目录
    最左前缀 从左往右用,不能只拿右边列
    EXPLAIN 查岗:看走没走索引

  • 索引是目录,乱建会添乱。
  • 普通索引常回表,字段够了叫覆盖。
  • 联合索引从左用,只查右列目录瞎。
  • EXPLAIN 看 type/key/rows,遇见 ALL 要警惕
  • 赞(0)
    未经允许不得转载:171主机测评 » 数据库 mysql 八股 3
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址