V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qwertyzzz
V2EX  ›  数据库

这个为什么会使用到索引呀

  •  
  •   qwertyzzz · 2021-05-21 14:32:44 +08:00 · 4744 次点击
    这是一个创建于 1284 天前的主题,其中的信息可能已经有所发展或是发生改变。

    微信图片_20210521142728.png 微信图片_20210521142734.png 微信图片_20210521142738.png

    看了下联合索引 不是最左原则吗 name 和 name,sex 应该都可以把 为什么单独一个 sex 也可以

    48 条回复    2021-05-25 11:56:42 +08:00
    sheeta
        1
    sheeta  
       2021-05-21 14:36:53 +08:00   ❤️ 1
    如果你的表再多一列,这个查询语句索引就会失效
    yinusxxxx
        2
    yinusxxxx  
       2021-05-21 14:37:05 +08:00
    我猜是 skip scan
    weizhen199
        3
    weizhen199  
       2021-05-21 14:37:12 +08:00
    什么库?
    又不是不可以。oracle 也有 index skip scan
    qwertyzzz
        4
    qwertyzzz  
    OP
       2021-05-21 14:39:05 +08:00
    @weizhen199 mysql ?
    qwertyzzz
        5
    qwertyzzz  
    OP
       2021-05-21 14:39:32 +08:00
    @sheeta 为啥哦
    qwertyzzz
        6
    qwertyzzz  
    OP
       2021-05-21 14:39:40 +08:00
    @yinusxxxx 我看看
    Suomea
        7
    Suomea  
       2021-05-21 14:46:25 +08:00
    可能是因为数据太少了,多弄点数据可以试试
    qwertyzzz
        8
    qwertyzzz  
    OP
       2021-05-21 14:48:25 +08:00
    @sheeta 试了下不会 还是有 Using index
    qwertyzzz
        9
    qwertyzzz  
    OP
       2021-05-21 14:48:33 +08:00
    @Suomea 我试试
    sheeta
        10
    sheeta  
       2021-05-21 14:48:53 +08:00
    @qwertyzzz 和你 select 字段有关系, 如果你的 select 字段只包含主键或联合索引中的部分,是仍然能够使用到索引的
    iminto
        11
    iminto  
       2021-05-21 14:55:42 +08:00
    联合索引从来都没有 “最左原则”这个规则,这个规则纯属某些人写博客瞎扯,然后以讹传讹。

    楼主可以试试三个字段的联合索引,你会发现,“最左原则”这种谎言会被一次次打脸。
    qwertyzzz
        12
    qwertyzzz  
    OP
       2021-05-21 15:08:14 +08:00
    @iminto 啊这 那我现在这个例子是不是就打破了呢。。
    qwertyzzz
        13
    qwertyzzz  
    OP
       2021-05-21 15:08:53 +08:00
    @sheeta 确实 加了新字段 如果 select 在里面 或者 select*就不会 但是看索引不是看 where 的吗。。我也不太明白
    iminto
        14
    iminto  
       2021-05-21 15:12:59 +08:00
    @qwertyzzz 如果是一个表建有三个字段 abc 的索引,那么无论 wher 条件里 abc 顺序如何,就算是 bca,cab 都能用上索引。如果 where 条件里只有两个字段,某些顺序可能无法用上索引,但一样是不遵循所谓最左匹配规则的。

    所以你可以忽略“最左匹配”这种说法。
    Jooooooooo
        15
    Jooooooooo  
       2021-05-21 15:17:59 +08:00   ❤️ 1
    @iminto 感觉你理解错了最左的含义.

    最左匹配是说, 如果创建了 abc 的联合索引, 那么 where 里只有 bc 或者 c 的情况下, 无法命中 abc 这个索引, 只有 a 或者 ab 才行.

    另外一个例子是如果 a 是一个范围查询, 那么会导致只能踩中 a 而 bc 失效了
    qwertyzzz
        16
    qwertyzzz  
    OP
       2021-05-21 15:21:23 +08:00
    @iminto 是哎 顺序无所谓 因为会自动帮你优化,但是 2 个和 3 个有区别吗
    @Jooooooooo 是额 最左匹配就是这个
    weizhen199
        17
    weizhen199  
       2021-05-21 15:23:53 +08:00   ❤️ 1
    @iminto 这是你自己理解有误
    aijam
        18
    aijam  
       2021-05-21 15:31:51 +08:00   ❤️ 2
    你可以试一试 select * from user; 他也会说是用到了 index 。这是一种特殊情况,和你后面 where 没太大关系。

    “In some cases, a query can be optimized to retrieve values without consulting the data rows. (An index that provides all the necessary results for a query is called a covering index.) ”
    参考: https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html

    也就是说,mysql 知道所有的数据都在 index 里,即使是 full scan 也直接从 index 里取了。你只要多加一个列,就不是 covering index 了,就不有这样的优化。
    qwertyzzz
        19
    qwertyzzz  
    OP
       2021-05-21 15:37:13 +08:00
    @aijam 是的耶
    jorneyr
        20
    jorneyr  
       2021-05-21 15:39:02 +08:00
    这个 index,应该指的是索引树,所有的索引信息都单独保存到索引树里了,你的查询正好只用到索引树中的一列。
    yeqizhang
        21
    yeqizhang  
       2021-05-21 15:40:49 +08:00 via Android
    @iminto 听你这么一说,上次因为看别人发面试题提到了问最左原则,我还去研究了一番,这就比较尴尬了
    iminto
        22
    iminto  
       2021-05-21 15:45:48 +08:00
    @Jooooooooo 如果三个字段的话,应该是只有 b,只有 c,只有 bc/cb,这三种情况会用不上索引。其余都可以
    iminto
        23
    iminto  
       2021-05-21 15:48:18 +08:00
    @Jooooooooo 也可以简单理解为只要有 a 就可以用到索引。这个如果按“最左”来理解,那倒确实是可以的。
    GuuJiang
        24
    GuuJiang  
       2021-05-21 15:51:33 +08:00   ❤️ 7
    @qwertyzzz 这里指的是覆盖索引,简单说就是不需要回表,只要你查询的列全都属于索引自然就满足覆盖索引
    @iminto 你才是属于以讹传讹吧,明明是你自己理解错误,谁说最左原则指的是在 where 里的顺序了?其实这是个简单的逻辑问题,如果 ABC 的组合是有序的,那么单独取出 AB 或者 A 仍然是有序的,这就是索引能继续发挥作用的原因,但是单独取出 B 、C 、BC 则不再是有序的,索引自然也就起不到作用了,这才是“最左原则”的本质
    zlowly
        25
    zlowly  
       2021-05-21 15:59:45 +08:00
    MySQL 8.0.13 开始支持 index skip scan 也即索引跳跃扫描。该优化方式支持那些 SQL 在不符合组合索引最左前缀的原则的情况,优化器依然能组使用组合索引。
    不过你这个测试数据太少,也不知道有没做表分析。建议生成个几万行测试数据,如果 sex 按含义只存放 2 种(或者几种)数据,估计就算你是独立的索引,优化器也不会选择用这个索引。
    skymei
        26
    skymei  
       2021-05-21 15:59:47 +08:00
    因为你的索引就覆盖了所有数据呀,覆盖了那必然会用到,你试试多加一列没索引的列,上面的索引就用不到了
    qwertyzzz
        27
    qwertyzzz  
    OP
       2021-05-21 16:04:22 +08:00
    @GuuJiang 应该是 你这个就感觉说到点了
    qwertyzzz
        28
    qwertyzzz  
    OP
       2021-05-21 16:07:14 +08:00
    @skymei 嗯嗯 上面有个和你说的一样 3q
    VincentYe123
        29
    VincentYe123  
       2021-05-21 16:13:05 +08:00
    @GuuJiang 他可能不知道有个查询优化器的东西
    tiedan
        30
    tiedan  
       2021-05-21 16:54:47 +08:00
    索引覆盖
    hhyyd
        31
    hhyyd  
       2021-05-21 19:10:52 +08:00
    @iminto where 里面的 abc,bca,cba 条件,mysql 会做优化,匹配到相关索引
    hhyyd
        32
    hhyyd  
       2021-05-21 19:16:33 +08:00
    @iminto 最左匹配的原则是, 他索引存的数据结构本身决定的。

    除非像楼上说的(索引跳跃扫描),mysql 再做其他优化, 不然就是最左匹配的
    Dganzh
        33
    Dganzh  
       2021-05-21 19:32:44 +08:00
    根据楼上说的,select 字段 from tb where ***, 这种语句只要字段有建索引就一定能走索引?跟 where 后面无关?
    zhongpingjing
        34
    zhongpingjing  
       2021-05-21 20:06:59 +08:00   ❤️ 3
    Using index 是使用索引覆盖的意思,type 为 index 代表扫描了整个索引树,也就是说这个查询没有用到索引来筛选数据
    shenqicai
        35
    shenqicai  
       2021-05-21 23:25:36 +08:00
    是上个月来我司面试要求拿走面试题目的那一位吗? 一模一样的题目
    littlewing
        36
    littlewing  
       2021-05-22 01:10:57 +08:00
    mysql 的执行计划中,对索引进行全表扫描也叫 using index,比如用到了覆盖索引的情况下,明显扫描索引比扫描主表更快,这也叫 using index
    medivh
        37
    medivh  
       2021-05-22 02:42:29 +08:00   ❤️ 2
    球球你们了,“性别” 是 Gender...
    leafre
        38
    leafre  
       2021-05-22 10:39:27 +08:00
    index,索引物理文件全扫描,和 all 差别不大
    JemGao
        39
    JemGao  
       2021-05-22 12:11:01 +08:00 via Android
    @medivh 😏
    Mitt
        40
    Mitt  
       2021-05-22 14:38:31 +08:00
    @medivh #37 这个大部分情况下用 sex 也没毛病吧
    honkki
        41
    honkki  
       2021-05-22 14:40:09 +08:00
    索引覆盖
    johnsona
        42
    johnsona  
       2021-05-22 15:26:58 +08:00 via iPhone
    @medivh oh are you sexy baby
    goodboy95
        43
    goodboy95  
       2021-05-23 14:30:14 +08:00
    @medivh 我又上网复习了一遍 sex 和 gender 的区别……话说中国大部分情况下也不用特意考虑社会性别吧
    raaaaaar
        44
    raaaaaar  
       2021-05-24 09:11:55 +08:00
    。。什么叫走索引?
    wangritian
        45
    wangritian  
       2021-05-24 12:55:49 +08:00
    24L 是正确答案,这里的 using index 指的是直接从索引树提取数据而无需从主键树回表,每棵索引树包含了主键+索引字段,楼主的 select *满足条件。因为不符合最左原则,它没有加速查询的效果,会扫描整颗索引树。
    25L 提到的索引跳跃,似乎只适合开头字段 distinct 值极少的情况,楼主以 name 开头肯定是用不上了。
    有个疑问是,为什么 mysql 引擎选择了覆盖索引而没有从主键树遍历?索引树的数据应该是以 name 排序的,查询结果是否符合?
    young1lin
        46
    young1lin  
       2021-05-25 00:25:44 +08:00
    @Mitt 确实是 Gender,如果你注册国外的网站的话,让你选是 Gender,不是 Sex 。

    还有个关于性别的冷知识,2014 年注册 Facebook 有 56 种非传统性别选择。具体看这个
    &t=14s
    Mitt
        47
    Mitt  
       2021-05-25 07:08:39 +08:00 via iPhone
    @young1lin 我觉得这跟 given name 和 first name 一样 有共同点,如果不特意强调社会性别的话只区分男女其他用 sex 应该也没有什么问题吧
    young1lin
        48
    young1lin  
       2021-05-25 11:56:42 +08:00
    @Mitt 是没什么问题,这个只要后面维护的人看得懂就行,这些字段主要是给人看的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3465 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:34 · PVG 19:34 · LAX 03:34 · JFK 06:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.