看了下联合索引 不是最左原则吗 name 和 name,sex 应该都可以把 为什么单独一个 sex 也可以
1
sheeta 2021-05-21 14:36:53 +08:00 1
如果你的表再多一列,这个查询语句索引就会失效
|
2
yinusxxxx 2021-05-21 14:37:05 +08:00
我猜是 skip scan
|
3
weizhen199 2021-05-21 14:37:12 +08:00
什么库?
又不是不可以。oracle 也有 index skip scan |
4
qwertyzzz OP @weizhen199 mysql ?
|
7
Suomea 2021-05-21 14:46:25 +08:00
可能是因为数据太少了,多弄点数据可以试试
|
10
sheeta 2021-05-21 14:48:53 +08:00
@qwertyzzz 和你 select 字段有关系, 如果你的 select 字段只包含主键或联合索引中的部分,是仍然能够使用到索引的
|
11
iminto 2021-05-21 14:55:42 +08:00
联合索引从来都没有 “最左原则”这个规则,这个规则纯属某些人写博客瞎扯,然后以讹传讹。
楼主可以试试三个字段的联合索引,你会发现,“最左原则”这种谎言会被一次次打脸。 |
13
qwertyzzz OP @sheeta 确实 加了新字段 如果 select 在里面 或者 select*就不会 但是看索引不是看 where 的吗。。我也不太明白
|
14
iminto 2021-05-21 15:12:59 +08:00
@qwertyzzz 如果是一个表建有三个字段 abc 的索引,那么无论 wher 条件里 abc 顺序如何,就算是 bca,cab 都能用上索引。如果 where 条件里只有两个字段,某些顺序可能无法用上索引,但一样是不遵循所谓最左匹配规则的。
所以你可以忽略“最左匹配”这种说法。 |
15
Jooooooooo 2021-05-21 15:17:59 +08:00 1
@iminto 感觉你理解错了最左的含义.
最左匹配是说, 如果创建了 abc 的联合索引, 那么 where 里只有 bc 或者 c 的情况下, 无法命中 abc 这个索引, 只有 a 或者 ab 才行. 另外一个例子是如果 a 是一个范围查询, 那么会导致只能踩中 a 而 bc 失效了 |
16
qwertyzzz OP |
17
weizhen199 2021-05-21 15:23:53 +08:00 1
@iminto 这是你自己理解有误
|
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 了,就不有这样的优化。 |
20
jorneyr 2021-05-21 15:39:02 +08:00
这个 index,应该指的是索引树,所有的索引信息都单独保存到索引树里了,你的查询正好只用到索引树中的一列。
|
21
yeqizhang 2021-05-21 15:40:49 +08:00 via Android
@iminto 听你这么一说,上次因为看别人发面试题提到了问最左原则,我还去研究了一番,这就比较尴尬了
|
22
iminto 2021-05-21 15:45:48 +08:00
@Jooooooooo 如果三个字段的话,应该是只有 b,只有 c,只有 bc/cb,这三种情况会用不上索引。其余都可以
|
23
iminto 2021-05-21 15:48:18 +08:00
@Jooooooooo 也可以简单理解为只要有 a 就可以用到索引。这个如果按“最左”来理解,那倒确实是可以的。
|
24
GuuJiang 2021-05-21 15:51:33 +08:00 7
|
25
zlowly 2021-05-21 15:59:45 +08:00
MySQL 8.0.13 开始支持 index skip scan 也即索引跳跃扫描。该优化方式支持那些 SQL 在不符合组合索引最左前缀的原则的情况,优化器依然能组使用组合索引。
不过你这个测试数据太少,也不知道有没做表分析。建议生成个几万行测试数据,如果 sex 按含义只存放 2 种(或者几种)数据,估计就算你是独立的索引,优化器也不会选择用这个索引。 |
26
skymei 2021-05-21 15:59:47 +08:00
因为你的索引就覆盖了所有数据呀,覆盖了那必然会用到,你试试多加一列没索引的列,上面的索引就用不到了
|
29
VincentYe123 2021-05-21 16:13:05 +08:00
@GuuJiang 他可能不知道有个查询优化器的东西
|
30
tiedan 2021-05-21 16:54:47 +08:00
索引覆盖
|
32
hhyyd 2021-05-21 19:16:33 +08:00
|
33
Dganzh 2021-05-21 19:32:44 +08:00
根据楼上说的,select 字段 from tb where ***, 这种语句只要字段有建索引就一定能走索引?跟 where 后面无关?
|
34
zhongpingjing 2021-05-21 20:06:59 +08:00 3
Using index 是使用索引覆盖的意思,type 为 index 代表扫描了整个索引树,也就是说这个查询没有用到索引来筛选数据
|
35
shenqicai 2021-05-21 23:25:36 +08:00
是上个月来我司面试要求拿走面试题目的那一位吗? 一模一样的题目
|
36
littlewing 2021-05-22 01:10:57 +08:00
mysql 的执行计划中,对索引进行全表扫描也叫 using index,比如用到了覆盖索引的情况下,明显扫描索引比扫描主表更快,这也叫 using index
|
37
medivh 2021-05-22 02:42:29 +08:00 2
球球你们了,“性别” 是 Gender...
|
38
leafre 2021-05-22 10:39:27 +08:00
index,索引物理文件全扫描,和 all 差别不大
|
41
honkki 2021-05-22 14:40:09 +08:00
索引覆盖
|
44
raaaaaar 2021-05-24 09:11:55 +08:00
。。什么叫走索引?
|
45
wangritian 2021-05-24 12:55:49 +08:00
24L 是正确答案,这里的 using index 指的是直接从索引树提取数据而无需从主键树回表,每棵索引树包含了主键+索引字段,楼主的 select *满足条件。因为不符合最左原则,它没有加速查询的效果,会扫描整颗索引树。
25L 提到的索引跳跃,似乎只适合开头字段 distinct 值极少的情况,楼主以 name 开头肯定是用不上了。 有个疑问是,为什么 mysql 引擎选择了覆盖索引而没有从主键树遍历?索引树的数据应该是以 name 排序的,查询结果是否符合? |
46
young1lin 2021-05-25 00:25:44 +08:00
@Mitt 确实是 Gender,如果你注册国外的网站的话,让你选是 Gender,不是 Sex 。
还有个关于性别的冷知识,2014 年注册 Facebook 有 56 种非传统性别选择。具体看这个 &t=14s |