mysql怎么会不走索引 mysql索引为什么不用跳表( 二 )


ex:select * from table_name where key1=1;
【mysql怎么会不走索引 mysql索引为什么不用跳表】如果key1列保存的是字符串,即使key1上有索引,也不会被使用 。
从上面可以看出 , 即使我们建立了索引,也不一定会被使用,那么我们如何知道我们索引的使用情况呢??在MySQL中,有Handler_read_key和Handler_read_rnd_key两个变量,如果Handler_read_key值很高而Handler_read_rnd_key的值很低 , 则表明索引经常不被使用 , 应该重新考虑建立索引 。可以通过:show status like 'Handler_read%'来查看着连个参数的值.
技术分享 | 为什么 SELECT 查询选择全表扫描,而不走索引?SQL的执行成本(cost)是 MySQL 优化器选择 SQL 执行计划时一个重要考量因素 。当优化器认为使用索引的成本高于全表扫描的时候 , 优化器将会选择全表扫描,而不是使用索引 。
下面通过一个实验来说明 。
如下结构的一张表,表中约有104w行数据:
查询1 , 并未用到ct_index(create_time)索引:
而查询2,则用到了ct_index(create_time)索引:
这里使用optimizer trace工具,观察MySQL对SQL的优化处理过程:
获得关于此SQL的详细优化器处理信息:
通过逐行阅读,发现优化器在join_optimization(SQL优化阶段)部分的rows_estimation内容里:
通过观察优化器的信息,不难发现 , 使用索引扫描行数约52w行,而全表扫描约为104w行 。为什么优化器反而认为使用索引的成本比全表扫描还高呢?
因为当ct_index(create_time)这个普通索引并不包括查询的所有列,因此需要通过ct_index的索引树找到对应的主键id,然后再到id的索引树进行数据查询,即回表(通过索引查出主键,再去查数据行),这样成本必然上升 。尤其是当回表的数据量比较大的时候 , 经常会出现MySQL优化器认为回表查询代价过高而不选择索引的情况 。
这里可以回头看查询1 和 查询2的数据量占比:
另外,在MySQL的官方文档中对此也有简要的描述:
参考文档:
索引失效的情况有哪些原因有如下:
1、最佳左前缀原则——如果索引了多列,要遵守最左前缀原则 。指的是查询要从索引的最左前列开始并且不跳过索引中的列 。
2、不在索引列上做任何操作 , 会导致索引失效而导致全表扫描 。
3、存储引擎不能使用索引中范围条件右边的列,范围之后索引失效 。这写条件判断最后放到后面,先定位到小的范围再开始 。
4、mysql使用不等于(!= 或者)的时候,无法使用索引 , 会导致索引失效 。
5、mysql中使用is not null 或者 is null会导致无法使用索引 。
6、mysql中like查询是以%开头,索引会失效变成全表扫描 , 覆盖索引 。
7、mysql中,如果条件中有or , 即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因) 。要想使用or,又想让索引生效 , 只能将or条件中的每个列都加上索引 。
8、如果mysql使用全表扫描要比使用索引快,则不会使用到索引 。
注意事项
1、索引列有函数处理或隐式转换,不走索引 。
2、索引列倾斜,个别值查询时,走索引代价比走全表扫描高 , 所以不走索引 。
3、索引列没有限制 not null,索引不存储空值 , 如果不限制索引列是not null,oracle会认为索引列有可能存在空值,所以不会按照索引计算 。
关于mysql怎么会不走索引和mysql索引为什么不用跳表的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。