概述

今天主要给大家介绍了关于MySQL InnoDB 二级索引的排序的相关资料,通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值。

每个InnoDB表具有一个特殊的索引称为聚簇索引(也叫聚集索引,聚类索引,簇集索引)。如果表上定义有主键,该主键索引就是聚簇索引。如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚簇索引。如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引。

表中的聚簇索引(clustered index )就是一级索引,除此之外,表上的其他非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。


排序问题

PS:本文的所有测试基于 MySQL 8 。

先把问题抛出来,下面的 SQL 所创建的表,有两个查询语句,哪个索引是非必须的?

CREATE TABLE `geek` ( `a` int(11) NOT NULL, `b` int(11) NOT NULL, `c` int(11) NOT NULL, `d` int(11) NOT NULL, PRIMARY KEY (`a`,`b`), KEY `c` (`c`), KEY `ca` (`c`,`a`), KEY `cb` (`c`,`b`)) ENGINE=InnoDB; select * from geek where c=N order by a limit 1;select * from geek where c=N order by b limit 1;

这里答案是索引 c 和 ca 的数据模型是一样的,因此 ca 是多余的。为啥??

我们知道,二级索引里存放的不是行的位置,而是主键的值,也知道索引是有序的。

如果 c 与 ca 的数据模型一样,那么就要求二级索引的叶子节点不仅是按索引列排序、而且还按关联的主键值进行排序。

我以前的理解是 二级索引只按索引列进行排序,主键值是不排序的。

问了大佬后得到的答复是:索引 c 就是按照 cab 这样排序,(二级索引))有保证主键算进去、还是有序的。

是不是?

如果能直接看 InnoDB 的数据文件,那就可以直接看出是不是遵循了这样的排序规则。可惜那是二进制文件,又没有顺手的工具可以方便查看,放弃。

后来找到了 MySQL 的 handler 语句,它支持 MyISAM/InnoDB 两种引擎的表。handler 语句提供了直接访问表存储引擎的接口。

下面的语法表示读取指定表指定索引的 第一条/前一条/下一条/最后一条 记录。

handler table_name/table_name_alias read index_name first/pre/next/last;

就用 handler 语句来验证下,先建一个简单的表,插入几条数据:

create table t_simple ( id int primary key, v int, key k_v (v)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; insert into t_simple values (1, 5);insert into t_simple values (10, 5);insert into t_simple values (4, 5);

上面的插入语句,二级索引列的值都是一样的,主键不是按顺序的,这样就可以看遍历时是不是按主键顺序存放的。

mysql> handler t_simple open as ts;Query OK, 0 rows affected (0.00 sec) mysql> handler ts read k_v next;+----+------+| id | v |+----+------+| 1 | 5 |+----+------+1 row in set (0.00 sec) mysql> handler ts read k_v next;+----+------+| id | v |+----+------+| 4 | 5 |+----+------+1 row in set (0.00 sec) mysql> handler ts read k_v next;+----+------+| id | v |+----+------+| 10 | 5 |+----+------+1 row in set (0.00 sec)

从结果可以看到,遍历的二级索引,值相等时,按主键的顺序遍历,基本可以确定二级索引不仅按索引列排序,还按主键值排序了。

为什么?

之前一直没看到说 MySQL 有这样的机制,问了前公司和先公司的 DBA 都没了解过这个。

最后 DBA 同事找到了 索引扩展, Index Extensions ,里面有这么段描述做了说明:

InnoDB automatically extends each secondary index by appending the primary key columns to it. Consider this table definition:

CREATE TABLE t1 (

i1 INT NOT NULL DEFAULT 0,

i2 INT NOT NULL DEFAULT 0,

d DATE DEFAULT NULL,

PRIMARY KEY (i1, i2),

INDEX k_d (d)

) ENGINE = InnoDB;

InnoDB 自动扩展每个二级索引,把主键值追加到索引列后面,把扩展后的组合列作为该索引的索引列。对于上面 t_simple 表的 k_v 索引,扩展后是 (v, id)列。

优化器会根据扩展后的二级索引的主键列来决定如何和是否使用那个索引。优化器可以用扩展的二级索引来进行 ref,range,index_merge 等类型的索引访问、松散的索引扫描、连接和排序优化,以及 min()/max() 优化。

可以用 show variables like '%optimizer_switch%'; 查看索引扩展是否开启;用 SET optimizer_switch = 'use_index_extensions=on/off'; 进行开启或关闭,这个只影响当前会话。

经测试,哪怕关闭了当前会话的索引扩展,用 handler 访问时仍然有按主键排序的效果。


总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值。

后面会分享更多DBA方面的内容,感兴趣的朋友可以关注下!!

mysql 排序后 下一条记录_什么是MySQL InnoDB 二级索引的排序?|附实例详解相关推荐

  1. mysql 排序后 下一条记录_Mysql如何使用order by工作

    日常开发中,我们经常要进行字段的排序,但是我们大多不知道排序是如何执行的,今天我们就说说order by 的执行逻辑, CREATE TABLE `t` (`id` int(11) NOT NULL, ...

  2. mysql 获取下一条记录数,如何在MySQL中查询当前数据上一条和下一条的记录

    如果ID是主键或者有索引,可以直接查找: 方法一: 查询上一条记录的SQL语句(如果有其他的查询条件记得加上other_conditions以免出现不必要的错误): select * from tab ...

  3. python中label有什么用_对Python中TKinter模块中的Label组件实例详解

    Python2.7.4 OS-W7x86 1. 简介 Label用于在指定的窗口中显示文本和图像.最终呈现出的Label是由背景和前景叠加构成的内容. Label组件定义函数:Label(master ...

  4. python url解码_对python中url参数编码与解码的实例详解

    一.简介 在python中url,对于中文等非ascii码字符,需要进行参数的编码与解码. 二.关键代码 1.url编码 对字符串编码用urllib.parse包下的quote(string, saf ...

  5. mysql获得每条记录_如何在MySQL查询结果集中得到每条记录的行号

    如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数. Oracle 中可以使用标准 ...

  6. oracle排序后的第一条记录

    该查寻语句没有经过任何的优化,因为oracle没有SQL的TOP关键字,但是有一个ROWNUM的列,因此,可以通过ROWNUM来进行查询.oracle的关于rownum的参考手册里面提到了    分析 ...

  7. mysql停电后无法启动不了_急求mysql 断电后无法启动解决方法!!!!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 RT,平台是windows+xampp,断电后开机无法启动mysql.errorlog如下 2014-08-14 08:01:35 2032 [Note] ...

  8. python3接口自动化测试_【python3+request】python3+requests接口自动化测试框架实例详解教程...

    前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自 ...

  9. linux下查看系统硬件,Linux 查看系统硬件信息 Linux 查看系统硬件信息(实例详解)...

    linux查看系统的硬件信息,并不像windows那么直观,这里我罗列了查看系统信息的实用命令,并作了分类,实例解说.html cpu lscpu命令,查看的是cpu的统计信息.linux blue@ ...

最新文章

  1. 【HDU】1084 What Is Your Grade? (结构体 sort)
  2. 独家 | 精选近期机器学习GitHub项目及Reddit热门话题(附链接)
  3. 灯光工厂滤镜插件knoll light factory
  4. 单细胞一站式分析网站CeDR Atlas使用指南
  5. Linux远程复制命令SCP
  6. 基于Docker持续交付平台建设的实践
  7. linux打开lua后中文有乱码,总结Lua使用中遇到的小问题
  8. 网络中的那些事儿(一)之神奇的通讯
  9. 《企业迁云实战》——2.4 云端实践
  10. python 构建来源gis_Python语言在ArcGIS环境中的应用.pptx
  11. MYSQL 表左连接 ON AND 和ON WHERE 的区别
  12. TLS协议簇加解密流程
  13. CTF PWN之heap入门 unlink
  14. Android模拟器网络连接问题解决,解决小蚁安卓模拟器网络异常无法连接的方法...
  15. ubuntu ibus-中文输入法
  16. linux下搭建svn仓库
  17. 暖风机家用最好的牌子 适合家用大面积的暖风机哪种好
  18. TypeScript下载安装
  19. Edgar--java中的delete小老弟的故事
  20. pyqt5出现 -1073741515 (0xC0000135) 错误的一个解决办法

热门文章

  1. [SOJ1006] Team Rankings
  2. 第一章:1.2.3 LTI系统研究方法与本章小结
  3. 改造我们的学习:有钱不会花,抱着金库抓瞎
  4. Java8 Map中新增的方法使用总结
  5. c# 说说开发通用通信库,尤其是分布式服务的通信
  6. cordova 打包工具
  7. 利用keepalived和haproxy配置mysql的高可用负载均衡
  8. Codeforces#363 Div2
  9. UA MATH566 例题 Poisson回归、Overdispersion与负二项回归
  10. UA MATH566 统计理论1 充分统计量例题答案3