V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
qmzhixu
V2EX  ›  MySQL

关于覆盖索引的问题

  •  
  •   qmzhixu · 2020-05-07 18:03:59 +08:00 · 3405 次点击
    这是一个创建于 1655 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近复习看到覆盖索引的概念,有一个 Innodb 表 user(id pk,age),id 为主键,使用 EXPLAIN SELECT id from user where id=1; 可以发现使用到了覆盖索引,但是执行 EXPLAIN SELECT age from user where id=1; 时发现 并未使用到覆盖索引,查的资料都说 InnoDB 聚集索引的叶子节点存储行记录应该包含有 age 这个字段的,但是这行查询并没有用到覆盖索引,是不是我理解有误了。

    17 条回复    2020-05-19 16:13:46 +08:00
    snappyone
        1
    snappyone  
       2020-05-07 18:21:24 +08:00 via Android
    你这个表一共就 2 列还弄啥覆盖索引
    Jacky23333
        2
    Jacky23333  
       2020-05-07 18:22:28 +08:00 via Android   ❤️ 2
    @snappyone 老实人
    qmzhixu
        3
    qmzhixu  
    OP
       2020-05-07 18:23:37 +08:00
    @snappyone 我是想搞懂这个原理,两个列只是方便看。。
    Jacky23333
        4
    Jacky23333  
       2020-05-07 18:25:48 +08:00 via Android
    聚集索引里面包含 age 字段跟 age 有没有加索引完全没有关系,你说的聚集索引其实只包含了 id 字段,你的 age 字段都没有索引那自然不会有索引覆盖
    qmzhixu
        5
    qmzhixu  
    OP
       2020-05-07 18:30:16 +08:00
    @Jacky23333 嗯,因为可以用到 id 找到叶节点里面的 age,按理也没有回表检索了,所以是不是覆盖索引都没区别了
    qmzhixu
        6
    qmzhixu  
    OP
       2020-05-07 18:32:01 +08:00
    @Jacky23333 只是执行计划里面的 extra 字段显示的是不是 Using index 而已
    imtemp
        7
    imtemp  
       2020-05-07 18:50:49 +08:00
    覆盖索引的概念理解有差异,看看这题
    https://segmentfault.com/q/1010000018998466
    imtemp
        8
    imtemp  
       2020-05-07 19:04:10 +08:00
    qumingkunnan
        9
    qumingkunnan  
       2020-05-07 20:41:48 +08:00 via Android
    索引覆盖是说通过索引查数据,然后查的数据刚好被索引包含了的意思吧?那么我理解你可以再加个字段 sex(这个字段可能加索引不太合适,只举例用),然后建立一个 age,sex 的索引,然后查询 age,sex 字段,条件用 age 或者 age,sex 。应该是满足索引覆盖的,验证下
    qmzhixu
        10
    qmzhixu  
    OP
       2020-05-07 21:13:53 +08:00
    @qumingkunnan 这种肯定是可以的,我指的是在聚集索引叶节点数据,不是其他的索引
    qumingkunnan
        11
    qumingkunnan  
       2020-05-07 22:11:53 +08:00 via Android
    @qmzhixu 接我上条回复,聚簇索引通常只是主键做索引,你说的叶子节点是聚簇索引这个存储结构的一部分,不是索引。聚簇索引是 innodb 中表的存储形式,而不仅仅是索引。
    gmhdbjd
        12
    gmhdbjd  
       2020-05-08 00:32:51 +08:00 via Android
    没赚你的 id 不是真的聚集索引
    Aresxue
        13
    Aresxue  
       2020-05-08 10:11:52 +08:00
    是否使用覆盖索引和 age 上面有没有索引有直接关系, 没有索引的话自然不会走覆盖索引, 而且你这个 age 还很有可能区分度 cardinality 不够或者数据量很小,CBO 发现全表扫描的 cost 反而比较小,那就直接扫全表喽
    Philyu
        14
    Philyu  
       2020-05-15 17:27:38 +08:00
    age 不在索引里面,mysql 先找到索引 id=1,然后回表去找 age,当然没有索引覆盖。
    Coolha
        15
    Coolha  
       2020-05-19 16:08:41 +08:00
    @Philyu 聚簇索引的叶子节点上存储的是数据,就不用回表了吧?
    Coolha
        16
    Coolha  
       2020-05-19 16:10:27 +08:00
    An index that includes all the columns retrieved by a query.

    id 所构成的索引不包括 age,所以不是覆盖索引
    Philyu
        17
    Philyu  
       2020-05-19 16:13:46 +08:00
    聚簇索引的一个典型例子就是主键,它直接存储数据字段,比如 id ;如果你要查 select id from xxxx where id>n
    这个当然不用回表;
    如果 id 是主键,另外建立了 age 的普通索引,那么 select age from xxx where id>n,是可以索引覆盖,不需要回表。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2520 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:20 · PVG 08:20 · LAX 16:20 · JFK 19:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.