MySQL中, in和or 会走索引吗

参考:
mysql or走索引吗_加了索引,mysql查询就一定会用吗?
InnoDB行锁变表锁的原因可能有哪些?(待总结...)

1.MySQL in 会用到索引吗?

        不一定,要看情况,具体是由MySQL优化器内部决定是全表扫描还是索引查找,用效率较高的一种方式

  1. 针对索引字段的唯一性不高的情况下(索引的"区分度"低),优化器可能会选择全表扫描,而不是走索引。这可能是因为等值查询符合条件的记录太多了,导致了mysql认为全表扫描比用索引查找更快。
    比如你对唯一性不高的字段(如性别:男/女)加了索引,这样通过索引去查找可能还需回表,还不如直接全表扫描!
  2. in中的数据量较大时,基本就不走索引了。如果你索引字段是一个unique,in可能就会用到索引。
  3. 如果你一定要用索引,可以用 force index。可能也和MySQL版本有关(5.6以后有做in的查询优化)。

        注:如果是 5.5 之前的版本确实不会走索引的,在 5.5 之后的版本,MySQL 做了优化。MySQL 在 2010 年发布 5.5 版本中,优化器对 in 操作符可以自动完成优化,针对建立了索引的列可以使用索引,没有索引的列还是会走全表扫描。


2.MySQL or 会用到索引吗?

        不一定,要看情况。or走索引与否,还和优化器的预估有关,就算连接条件都设置了索引,也可能因为回表导致索引失效。

        索引优化器的存在,就是找到一个索引扫描行数最少的方案去执行语句。那么扫描行数怎么来判断的?是逐行统计数据表的数据吗?其实并不是,而是根据统计信息来预估的值,这个统计信息就是我们常说的索引的“区分度”。

        显然,一个索引上不同的值越多,这个索引的区分度就越好。我们把一个索引上不同的值的个数,称之为 "索引基数"。也就是说,基数越大,索引的区分度就越好,执行查询的行数就越少。如何查看索引基数呢?使用 show index from 表名,其中cardinality字段显示的就是索引的基数。

        扩展:MySQL 是怎样得到索引基数的呢?不感兴趣的小伙伴可以飘过啦~
        索引基数 = 采样统计*页数。采样统计就是避免把整张表取出来一行行统计做精准计算,以免消耗系统性能。在采样统计时,InnoDB默认会选择 N 个数据页,统计这些页面上的 "对应索引字段" 上不同值的个数,得到一个平均值,然后用平均值乘以这个索引的页面数,就得到了这个索引的基数。统计信息不是固定不变的,他会随着数据表的变化而变化。当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。

        建议:在使用前最好还是先用 explain 来试试到底sql语句走不走索引,然后选择较优的sql

  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值