0


【MySQL 10】索引

1.初始索引


1.1索引概念

    提高数据库的性能,索引是物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行正确的 create index ,查询速度就可能提高成百上千倍。

    但是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的IO。

    所以它的价值,在于提高一个海量数据的检索速度。

1.2常见索引分类

  • 主键索引(primary key)
  • 唯一索引(unique)
  • 普通索引(index)
  • 全文索引(fulltext)--解决中子文索引问题。

1.3 见一下索引(案例)

先整一个海量表,在查询的时候,看看没有索引时有什么问题?
--构建一个8000000条记录的数据,创建存储过程,向雇员表添加海量数据

1.创建好数据库

drop database if exists `test_index`;
create database if not exists `test_index` default character set utf8;
use `test_index`;

2.产生随机字符串

delimiter $$
create function rand_string(n INT)
    returns varchar(255)
begin
    declare chars_str varchar(100) default
        'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
    declare return_str varchar(255) default '';
    declare i int default 0;
    while i < n
        do
            set return_str = concat(return_str, substring(chars_str, floor(1 + rand() * 52), 1));
            set i = i + 1;
        end while;
    return return_str;
end $$
delimiter ;

3.产生随机数字

delimiter $$
create function rand_num()
    returns int(5)
begin
    declare i int default 0;
    set i = floor(10 + rand() * 500);
    return i;
end $$
delimiter ;

4.创建存储过程,向雇员表添加海量数据

delimiter $$
create procedure insert_emp(in start int(10), in max_num int(10))
begin
    declare i int default 0;
    set autocommit = 0;
    repeat
        set i = i + 1;
        insert into EMP
        values ( (start + i)
               , rand_string(6), 'SALESMAN', 0001, curdate(), 2000, 400, rand_num());
    until i = max_num
        end repeat;
    commit;
end $$
delimiter ;

5.创建员工表。

CREATE TABLE `EMP`
(
    `empno`    int(6) unsigned zerofill NOT NULL     COMMENT '雇员编号',
    `ename`    varchar(10)              DEFAULT NULL COMMENT '雇员姓名',
    `job`      varchar(9)               DEFAULT NULL COMMENT '雇员职位',
    `mgr`      int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',
    `hiredate` datetime                 DEFAULT NULL COMMENT '雇佣时间',
    `sal`      decimal(7, 2)            DEFAULT NULL COMMENT '工资月薪',
    `comm`     decimal(7, 2)            DEFAULT NULL COMMENT '奖金',
    `deptno`   int(2) unsigned zerofill DEFAULT NULL COMMENT '部门编号'
);

6.执行存储过程,添加8000000条记录

call insert_emp(100001, 8000000);

此时我们没有添加任何的索引。

  • 查询员工编号为998877的员工

    可以看到耗时8.14秒,这还是在本机一个人来操作,在实际项目中,如果放在公网中,假如同时有1000个人并发查询,那很可能就死机。
  • 解决方法,创建索引

      此时就建立好索引了
    

  • 换一个员工编号,测试看看查询时间

由于建立了索引,现在查询任何一个人,基本就没有什么时间消耗了


2.关于物理磁盘

    MySQL 给用户提供存储服务,而存储的都是数据,数据在磁盘这个外设当中。磁盘是计算机中的一个机械设备,相比于计算机其他电子元件,磁盘效率是比较低的,在加上IO本身的特征,可以知道,如何提交效率,是 MySQL 的一个重要话题。

2.1见一下物理磁盘

我们都知道计算机只认识二进制:二进制不就是0和1吗,那么什么是0和1呢?

    0和1在计算机中分别代表“关闭”和“打开”的状态;在计算机内部,所有的数据、文本、图像、音频、视频等各种类型的信息都被转换为二进制码进行处理;在数字逻辑中,0和1可以用来表示逻辑值,如“假”和“真”,或者表示电路的关闭和打开状态。在内存和存储器中,所有的数据都以二进制形式存储,包括变量、数组、数据结构等。**上面的0,1都是被规定出来的,但0,1在物理层面会有不同的表现。**

普通磁盘:

企业级磁盘(服务器):


2.2 了解磁盘的存储结构

磁盘的存储结构主要包括以下几个方面:

  • 盘片:磁盘由多个盘片组成,这些盘片是圆形的坚硬表面,通过引入磁性变化来永久存储数据。盘片通常由一些硬质材料(如铝)制成,然后涂上薄薄的磁性层,即使驱动器断电,也能持久存储数据位。每个盘片有两面,每面都称为表面,都可以记录信息。
  • 磁道与扇区:每个盘片被划分为若干个磁道(半径不同的同心圆环),每个磁道又被划分为若干个扇区(磁道上的一个弧段)。扇区是磁盘的最小组成单元,通常是512字节。(读写数据的基本单位)在数据传输过程中,数据是按扇区进行存放和读取的。

  • 柱面:硬盘中,所有盘面中半径相同的磁道组成柱面。由于所有磁头都是连在同一个磁臂上的,因此所有磁头只能同时读写同一柱面的不同盘面。

  • 磁头:每个盘面对应一个磁头,磁头负责读写磁盘上的数据。磁头悬浮在磁盘表面,通过步进电机在不同柱面之间移动,以实现对不同柱面的读写操作。

      读写操作:当计算机需要读取或写入数据时,磁盘驱动器会接收到指令并将磁头移动到相应的磁道上。在读取数据时,**磁头会感应到磁盘表面磁性材料上的磁场变化,并将其转换为电信号(即二进制数据)。这些电信号随后被解码为计算机可以理解的0和1。在写入数据时,磁盘驱动器会将计算机发送的二进制数据(0和1)转换为磁场信号,并通过磁头将这些信号写入磁盘的指定位置。(**CHS定址法**)(**这些磁性材料具有稳定的磁化特性,即使在磁盘停止转动和电源关闭的情况下,也能保持其磁化状态不变。这意味着存储在磁盘上的数据可以长时间保持而不丢失。**)**
    
      0和1的表示:在机械磁盘中,0和1是通过磁盘表面磁性材料的磁场方向来表示的。当磁性材料被磁化为一个特定的方向时,它表示一个二进制位(bit)的0或1。通过改变磁盘上磁性材料的磁场方向,磁盘可以存储大量的二进制数据。
    

2.3对磁盘的逻辑结构进行抽象

在这里我们走一遍OS对磁盘这样的设别进行管理和抽象。

假如我们有800G 的内存,我们假如每一个盘面200G,这样我们在OS中就可以拼凑出一段连续的内存。每个面上又有若干个扇区(sector)。 这样我么们就得到一个数组了,那我们就可以通过下标去访问每一个扇区了。接下来我们就只需要将下标转化为CHS就可以访问磁盘中对应的位置了。

假如每一个盘面有1000个扇区,同时它有十个磁道,那么每个磁道就有100个扇区。

  • 我们用index表示某个扇区的下标
  • 那么index/1000 就能获得该扇区位于哪个盘面了H(Heads)。
  • index%1000=temp;[0,999](表示第一面1000个扇区中的某一个扇区)
  • temp/100=C (Cylinder)(表示扇区对应的磁道) 同半径的磁道,整体上构成了一个柱面。在确定了盘面之后,再确定柱面即可确定数据在盘面上的哪一个磁道。
  • temp%100=S(Sector) (每个磁道有100个,那么%100就能得到对应的扇区了。)

通过上面的操作我们就将OS中的线性地址转化为磁盘中的CHS地址了。(index->CHS)

那么,我们就可以知道了,文件=很多个sector的数组的下标!!!

    我们上面提到过,磁盘的基本读写单位是512字节,这是非常小的,效率比较低。

一般而言,OS未来和磁盘交互的时候,基本单位(规定出来的):4KB(8*sector)8个连续的扇区,后面我们会将这个称为数据块,每个块都有对应的块号。那么,我们就可以认为,文件=很多个数据块。那么,我们通过块读取,我们就可以一次读取8个 扇区的下标,然后通过这些下标再次去走上面(index->CHS)的逻辑,我们就可以以块进行读取数据了。

  **  对于OS而言,只需要知道块的起始标号和磁盘的大小,我们就可以活得磁盘内所有的数据了。我们将块的标号称为LBA 逻辑区块地址 (Logical Block Address, LBA)。**

解下来解释分区的概念:整个800G就是一个LBA blacks[N]数组,如果我们整个只要将内存通过LBA标记起始位置和结束位置,此时我们就将内存分区了。


4.磁盘随机访问与连续访问

  • 随机访问:本次IO所给出的扇区地址和上次IO给出扇区地址不连续,这样的话磁头在两次IO操作之间需要作比较大的移动动作才能重新开始读/写数据。
  • 连续访问:如果当次IO给出的扇区地址与上次IO结束的扇区地址是连续的,那磁头就能很快的开始这次IO操作,这样的多个IO操作称为连续访问。
  • 因此尽管相邻的两次IO操作在同一时刻发出,但如果它们的请求的扇区地址相差很大的话也只能称为随机访问,而非连续访问。
  • 磁盘是通过机械运动进行寻址的,随机访问不需要过多的定位,故效率比较高。

5.MySQL表与磁盘

    在MySQL中,数据库其实就是目录,表其实就是一个文件。数据库的文件就存储在
/var/lib/mysql

路径下,这些文件,最后都是会被写入到磁盘中的。


3. MySQL 与磁盘的交互

3.1MySQL 与磁盘的交互基本单位

    而 MySQL 作为一款应用软件,可以想象成一种特殊的文件系统。它有着更高的IO场景,所以,为了提高基本的IO效率, MySQL 进行IO的基本单位是 16KB(这是在InnoDb存储引擎下)

    查看InnoDb下IO的基本单位
SHOW GLOBAL STATUS LIKE 'innodb_page_size';


也就是说,磁盘这个硬件设备的基本单位是 512 字节,而 MySQL InnoDB引擎 使用 16KB 进行IO交互。即, MySQL 和磁盘进行数据交互的基本单位是 16KB 。这个基本数据单元,在 MySQL 这里叫做page(注意和系统的page区分)

3.2 MySQL数据如何和磁盘交互

    在上面我们谈过,OS与磁盘进行一次数据交互的基本单位是 4KB,但是MySQL一次就是16KB,这是如何做到的?
  • Read

      MySQL服务作为应用层,是不能直接从磁盘读取数据的,它是要调用OS接口的。
    
      当MySQL需要读取数据时,它首先会检查其内存中的缓存池,如果所需数据不在缓存池(Buffer Pool)中,MySQL会向操作系统发出请求,操作系统随后从磁盘中读取数据,OS向磁盘中读取数据到文件缓冲区中,直到16KB,然后MySQL从文件系统缓存中将其复制到其内部的缓存池中。
    
  • Write

      当MySQL需要写入数据时,它首        先会在内存中的缓存池中进行修改。修改后的数据被标记为“脏数据”,表示它们尚未被写回到磁盘。MySQL会根据其刷新策略(如脏数据达到一定量或一定时间间隔后)将脏数据从缓存池刷新到操作系统的内核缓冲区。操作系统随后根据自身的策略将内核缓冲区中的数据写回到磁盘。
    

4.建立共识

  • MySQL 中的数据文件,是以page为单位保存在磁盘当中的。
  • MySQL 的 CURD 操作,都需要通过计算,找到对应的插入位置,或者找到对应要修改或者查询的数据。
  • 而只要涉及计算,就需要CPU参与,而为了便于CPU参与,一定要能够先将数据移动到内存当中。
  • 所以在特定时间内,数据一定是磁盘中有,内存中也有。后续操作完内存数据之后,以特定的刷新策略,刷新到磁盘。而这时,就涉及到磁盘和内存的数据交互,也就是IO了。而此时IO的基本单位就是Page。
  • 为了更好的进行上面的操作, MySQL 服务器在内存中运行的时候,在服务器内部,就申请了被称为 Buffer Pool 的的大内存空间(一般默认大小为 128M),来进行各种缓存。其实就是很大的内存空间,来和磁盘数据进行IO交互。
  • 为何更高的效率,一定要尽可能的减少系统和磁盘IO的次数

5.索引的理解

5.1 案例

    **创建一张表,这里我们将id设置成为主键索引,设置主键后,即使插入主键数据无序,MySQL也会自动安装主键进行排序**(一定要添加主键哦,只有这样才会默认生成主键索引)

    向表中插入数据,但我们在插入时,故意不按顺序插入id

    查看表中数据,发现已经按照主键id拍好了


5.2 理解page

    在 MySQL 中,尤其是在使用 InnoDB 存储引擎时,Page 是一个非常重要的概念。Page 是 InnoDB 存储数据的基本单位,而如何高效地管理这些 Page 是数据库性能优化的关键之一。
  • MySQL内部,一定需要并且存在大量的page,也就决定了,mysql必须要将多个同时存在的page管理起来!
  • 我们不能简单的将page 认为是一个内存块,page内部页必须写入对应的管理信息, 需要用链表将多个page管理起来

以下是page的结构:

struct Page
{
    struct Page* next;
    struct Page* prev;
    char buffer[NUM];
};    // 16 KB
    当你申请一个page,实际就是new Page(),将所有的page用链表的形式管理起来。

** 为何MySQL和磁盘进行IO交互的时候,要采用Page的方案进行交互呢?用多少,加载多少不香吗?**
如上面的5条记录,如果MySQL要查找id=2的记录,第一次加载id=1,第二次加载id=2,一次一条记录,那么就需要2次IO。如果要找id=5,那么就需要5次IO。
但,如果这5条(或者更多)都被保存在一个Page中(16KB,能保存很多记录),那么第一次IO查找id=2的时候,整个Page会被加载到MySQL的Buffer Pool中,这里完成了一次IO。但是往后如果在查找id=1,3,4,5等,完全不需要进行IO了,而是直接在内存中进行了。所以,就在单Page里面,大大减少了IO的次数。
你怎么保证,用户一定下次找的数据,就在这个Page里面?我们不能严格保证,但是有很大概率,因为有局部性原理。
往往IO效率低下的最主要矛盾不是IO单次数据量的大小,而是IO的次数。


5.2.1理解单个Page
    MySQL 中要管理很多数据表文件,而要管理好这些文件,就需要 先描述,在组织 ,我们目前可以简单理解成一个个独立文件是有一个或者多个Page构成的

    不同的 Page ,在 MySQL 中,都是 16KB ,使用 prev 和 next 构成双向链表。

    因为有主键的问题, MySQL 会默认按照主键给我们的数据进行排序,从上面的Page内数据记录可以看出,数据是有序且彼此关联的。

    插入数据排好序,实际上就是为了优化查询效率,单链表是从头开始查找的,在有序的情况下,没有任何一个查找是浪费的,而且,如果运气好,是可以提前结束查找过程的。

5.2.2 理解多个pag
  • 通过上面的分析,我们知道,上面页模式中,只有一个功能,就是在查询某条数据的时候直接将一****整页的数据加载到内存中,以减少硬盘IO次数,从而提高性能。但是,我们也可以看到,现在的页模式内部,实际上是采用了链表的结构,前一条数据指向后一条数据,本质上还是通过数据的逐条比较来取出特定的数据。
  • 如果有1千万条数据,一定需要多个Page来保存1千万条数据,多个Page彼此使用双链表链接起来,而且每个Page内部的数据也是基于链表的。那么,查找特定一条记录,也一定是线性查找。这效率也太低了

5.3 页目录

    我们再看一本书的时候,我国我们要翻到哪一章节,找到该章节有两种做法:
  • 从头逐页的向后翻,直到找到目标内容
  • 通过书提供的目录,发现指针章节在234页(假设),那么我们便直接翻到234页。同时,查找目录的方案,可以顺序找,不过因为目录肯定少,所以可以快速提高定位
  • 本质上,书中的目录,是多花了纸张的,但是却提高了效率
  • 所以,目录,是一种“空间换时间的做法”

5.3.1 单页page
    针对上面的情况,我们当然也能页目录。

    那么当前,在一个Page内部,我们引入了目录。比如,我们要查找id=4记录,之前必须线性遍历4次,才能拿到结果。现在直接通过目录2[3],直接进行定位新的起始位置,提高了效率。

    现在我们可以再次正式回答上面的问题了,为何通过键值 MySQL 会自动排序?

   ** 可以很方便的引入目录**

5.3.2 多页page
    MySQL 中每一页的大小只有 16KB ,单个Page大小固定,所以随着数据量不断增大, 16KB 不可能存下所有的数据,那么必定会有多个页来存储数据

    在单表数据不断被插入的情况下, MySQL 会在容量不足的时候,自动开辟新的Page来保存新的数据,然后通过指针的方式,将所有的Page组织起来。
     我们就可以通过多个Page遍历,Page内部通过目录来快速定位数据。可是,貌似这样也有效率问题,在Page之间,也是需要 MySQL 遍历的,遍历意味着依旧需要进行大量的IO,将下一个Page加载到内存,进行线性检测。这样就显得我们之前的Page内部的目录,有点杯水车薪了。显然这个方法只能解决较少的page,一旦page非常的多,效率仍然是底下的,因此我们要引入新的管理方法,B+树。

5.3.3 用B+树管理多页page(innode dp下索引结构)
    这时二级索引的叶子节点包含主键值,而不是实际数据行。通过二级索引查找数据时,需要首先找到主键值,然后通过主键值在聚集索引中查找实际数据。实际上就是给页目录再左页目录,如果这样还不够 ,那就再多加一层,最终形成B+树结构。 **实际B+树,只有叶子节点是使用链表连接起来的,其它层是没有的。**![](https://i-blog.csdnimg.cn/direct/ca540983ebce4ab281a3b98011543325.png)

底层操作:

  1. 从根节点开始,根据键值比较找到相应的子节点指针。
  2. 递归地遍历内部节点,直到到达叶子节点。
  3. 在叶子节点中查找目标键值,如果找到,则根据指针找到实际数据页。

优点:

  • 平衡性(搜索效率):B+树始终保持平衡,保证了查找、插入和删除操作的时间复杂度为O(log n)。
  • 磁盘I/O效率:叶子节点保存有数据,路上节点没有,非叶子节点不要数据,只要目录,因此非叶子节点可以存更多的目录项,管理更多的叶子page,导致B+树一定是一个矮胖树,也就意味着途径路上节点减少,减少了磁盘I/O操作次数,因为每次查找只需访问较少的节点。
  • 顺序访问:叶子节点形成链表,便于范围查询(一个区间)和顺序扫描。

** 如果用户没有主键,MySQL会自己生成一个隐藏列,这个隐藏列天然就有主键。**


5.3 只能是B+树吗?其他数据结构呢?

    AVL &&红黑树?虽然是平衡或者近似平衡,但是毕竟是二叉结构,相比较多阶B+,意味着树整体过高,大家都是自顶向下找,层高越低,意味着系统与硬盘更少的IO Page交互。虽然你很秀,但是有更秀的。

    Hash?官方的索引实现方式中, MySQL 是支持HASH的,不过 InnoDB 和 MyISAM 并不支持.Hash跟进其算法特征,决定了虽然有时候也很快(O(1)),不过,在面对范围查找就明显不行

5.4 B+ vs B

B树

B+树

目前这两棵树,对我们最有意义的区别是:

  • B树节点,既有数据,又有Page指针,而B+,只有叶子节点有数据,其他目录页,只有键值和Page指针
  • B+叶子节点,全部相连,而B没有

为何选择B+

  • 节点不存储data,这样一个节点就可以存储更多的key。可以使得树更矮,所以IO操作次数更少。
  • 叶子节点相连,更便于进行范围查找

5.5 聚簇索引 VS 非聚簇索引

5.5.1MyISAM和InnoDB

MyISAM 存储引擎-主键索引
MyISAM 引擎同样使用B+树作为索引结果,叶节点的data域存放的是数据记录的地址。下图为 MyISAM表的主索引, Col1 为主键。

    其中, **MyISAM 最大的特点是,将索引Page和数据Page分离,也就是叶子节点没有数据,只有对应数据的地址**

** 相较于 InnoDB 索引, InnoDB 是将索引和数据放在一起的。**

    MySQL 除了默认会建立主键索引外,我们用户也有可能建立按照其他列信息建立的索引,一般这种索引可以叫做辅助(普通)索引。
     对于 MyISAM ,建立辅助(普通)索引和主键索引没有差别,无非就是主键不能重复,而非主键可重复。下图就是基于 MyISAM 的 Col2 建立的索引,和主键索引没有差别

    同样, InnoDB 除了主键索引,用户也会建立辅助(普通)索引,我们以上表中的 Col3 建立对应的辅助索引如下图:

    可以看到, InnoDB 的非主键索引中叶子节点并没有数据,而只有对应记录的key值。
     所以通过辅助(普通)索引,找到目标记录,需要两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。这种过程,就叫做**回表查询**

5.5.2 聚簇索引与非聚簇索引
    MyISAM 这种用户数据与索引数据分离的索引方案,叫做非聚簇索引
     InnoDB 这种用户数据与索引数据在一起索引方案,叫做聚簇索引

案例:

    .ibd文件是InnoDB存储引擎特有的文件格式,用于存储表,索引和索引的数据,索引和索引的数据都在一个文件中,因此我们称之为聚簇索引。 

.sdi

文件包含了表的定义和结构信息,

.MYD

文件是MyISAM存储引擎中的数据文件,

.MYI

文件是MyISAM表的索引文件,索引和索引的数据不在一个文件中,因此我们称之为非聚簇索引。


6.索引操作


6.1创建索引

6.1.1创建主键索引

关键字:primary key

方法一:在创建表的时候,直接在字段名后指定 primary key

方法二:在创建表的最后,指定某列或某几列为主键索引

方法三:创建表以后再添加主键

主键索引的特点:

  • 一个表中,最多有一个主键索引,当然可以使符合主键
  • 主键索引的效率高(主键不可重复)
  • 创建主键索引的列,它的值不能为null,且不能重复
  • 主键索引的列基本上是int

6.1.2 唯一索引的创建

关键字:unique

方法一:在表定义时,在某列后直接指定unique唯一属性。‘

方法二:创建表时,在表的后面指定某列或某几列为unique

方法三:创建表后再添加

唯一索引的特点:

  • 一个表中,可以有多个唯一索引
  • 查询效率高
  • 如果在某一列建立唯一索引,必须保证这列不能有重复数据
  • 如果一个唯一索引上指定not null,等价于主键索引

6.1.3 普通索引创建

关键字:index

方法一:在表的定义最后,指定某列为索引

方法二:创建完表以后指定某列为普通索引

方法三:创建一个索引名为 idx_name 的索引

普通索引的特点:

  • 一个表中可以有多个普通索引,普通索引在实际开发中用的比较多
  • 如果某列需要创建索引,但是该列有重复的值,那么我们就应该使用普通索引

6.1.4 全文索引的创建

关键字: fulltext

    当对文章字段或有大量文字的字段进行检索时,会使用到全文索引。MySQL提供全文索引机制,但是有要求,要求表的存储引擎必须是MyISAM,而且默认的全文索引支持英文,不支持中文。如果对中文进行全文检索,可以使用sphinx的中文版(coreseek)

看下面例子:

** **这行代码为

title

body

字段创建了一个全文索引。

    插入一组数据。

使用全文索引:

    当我们使用普通查询的时候,他是不会去使用全文索引。

    我们可以使用explain工具查看一下,是否使用索引。**explain可以查看sql语句执行计划**

    key为NULL,表示没有用到索引:

**关键字:match 要匹配的索引,against 要匹配的关键字
**样例。 ** **

    我们再使用explain查看。

    确实就使用了title 和 body的复合索引


6.1.5索引创建原则
  • 比较频繁作为查询条件的字段应该创建索引
  • 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
  • 更新非常频繁的字段不适合作创建索引
  • 不会出现在where子句中的字段不该创建索引

6.2 查询索引

方法一:show keys from 表名

    Column_name :在这个例子中,它是“id”,表示这个索引是基于“id”列的。


字段名中文翻译解释Non_unique非唯一性如果索引不能包含重复词,则该列的值为0。如果可以,则该列的值为1。对于主键索引,这个值总是0,因为主键必须是唯一的。Key_name键名索引的名称。在这个例子中,它是“PRIMARY”,表示这是一个主键索引。Seq_in_index在索引中的序列索引中的列序列号,从1开始。对于单列索引,这个值总是1。Column_name列名索引中的列名。在这个例子中,它是“id”,表示这个索引是基于“id”列的。Collation排序规则列以什么顺序存储在索引中。'A' 表示升序,NULL 表示不适用。对于主键索引,这个值通常是A,因为主键默认按升序排序。Cardinality基数索引中唯一值的估计数量。这个值是一个估计值,可能不准确。0表示MySQL无法估计基数。Sub_part子部分如果索引只是列的一部分,则该列包含索引的字符数。对于全文索引,这是每个索引词的最大字符数。NULL表示索引了整个列。Packed压缩指示关键字如何被压缩。如果没有被压缩,则为NULL。Null空值如果列可以包含NULL,则该列为'YES'。如果不可以,则该列为''(空字符串)。对于主键索引,这个值通常是'',因为主键列不能包含NULL值。Index_type索引类型使用的索引方法(BTREE, FULLTEXT, HASH, RTREE)。在这个例子中,它是BTREE,这是MySQL中最常用的索引类型。Comment注释关于索引的额外信息。在这个例子中,它是空的。Index_comment索引注释关于索引的额外信息(仅对MyISAM和InnoDB表适用)。在这个例子中,它也是空的。Visible可见性索引是否对优化器可见。YES表示索引可见,可以用于查询优化。Expression表达式如果索引是一个函数索引或计算列索引,则该列显示表达式。对于普通索引,这个值是NULL。 方法二:show index from 表名;


方法三:desc 表名;

6.3 删除索引

第一种方法-删除主键索引: alter table 表名 drop primary key;

第二种方法-其他索引的删除: alter table 表名 drop index 索引名; 索引名就是show keys
from 表名中的 Key_name 字段

    user8 唯一键name

删除user8中唯一键:name

第三种方法-其他索引的删除:drop index 索引名 on 表名

标签: mysql 数据库

本文转载自: https://blog.csdn.net/2301_76618602/article/details/142750270
版权归原作者 momo小菜pa 所有, 如有侵权,请联系我们删除。

“【MySQL 10】索引”的评论:

还没有评论