MySQL之主键索引排序失效问题
主键索引排序失效
环境:MySQL8
有一张用户信息表user_info
,建表DDL如下:
CREATE TABLE `user_info` ( `id` int(11) NOT NULL COMMENT '用户编号', `age` int(11) NOT NULL COMMENT '用户年龄', PRIMARY KEY (`id`), KEY `idx_age` (`age`) USING BTREE COMMENT '年龄索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
只有两列,第一列用户编号id
做主键,第二列用户年龄age
有一个普通索引idx_age
。
现在初始化几行数据
INSERT INTO `user_info` (`id`,`age`) VALUES(1,1),(5,3),(7,8),(11,12);
查一下所有记录
接着往这个表里插入一行数据(6,1)
,猜测一下这行数据最终会插入在什么位置?
可能大部分人都会认为插入在(5,3)
和(7,8)
之间,因为id=6的话,5<6<7。
但是再次查看结果,发现并符合预期,而是插入在了(1,1)
和(5,3)
之间:
看起来效果就像是age
变为了主键,根据age
默认排序了,或者说主键索引排序失效。
这是因为在MySQL底层实现中,对于像user_info
这种特殊的表,有特殊的处理方式。这张user_info
表的特殊点在于,只有两列,一列是主键,另一列也有索引。
这时候非主键的age这一列就是一个覆盖索引
,因为age的索引可以查到所有字段。
MySQL内部会认为访问数据的时候,覆盖索引的效率比主键索引高,所以维护默认的排序会优先根据覆盖索引列来进行。
查看一下执行计划
type=index
,代表只遍历了索引树;key=idx_age
,代表真正用到了索引;Extra=Using index
,代表覆盖索引生效,在索引树中就可以查到所需数据,避免了回表扫描表数据文件。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
安装mysql-8.0.19-winx64遇到的问题:Can''t create directory ''xxxx\Da
这篇文章主要介绍了安装mysql-8.0.19-winx64遇到的坑 ,Can't create directory 'xxxx\Database\',非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下2020-02-02mysql+mybatis实现存储过程+事务 + 多并发流水号获取
这篇文章主要介绍了mysql+mybatis+存储过程+事务 + 多并发流水号获取,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-12-12mysql installer community 8.0.16.0安装配置图文教程
这篇文章主要为大家详细介绍了mysql installer community 8.0.16.0安装配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2019-05-05
最新评论