首页 > 数据库 >Mysql索引

Mysql索引

时间:2024-12-28 20:26:34浏览次数:7  
标签:index name ## 查询 索引 Mysql 主键

1、什么是索引

        索引是数据库中一种特殊存储结构,旨在提高数据检索性能,提高访问速度,且是有序的。InnoDB存储引擎中有 主键索引,唯一索引,普通索引,全文索引 四类索引。

        注意:索引在InnoDB存储引擎中 与数据存储在一起的。

1.1、主键索引

        概念:数据库只有一个唯一索引,唯一且不重复。

        主键索引生成策略:

        1、数据表有主键(primary key),则 以primary key为主键索引。

        2、数据表未设置主键(primary key),但创建了唯一索引,则 以唯一索引值 为主键索引。

        3、数据表既没有创建主键也没有创建唯一索引,则 Mysql默认采用 DB_ROW_ID为主键索引。(这也是系统默认创建主键索引)

        语法:

## table_name 表名
## column_name 字段名
ALTER TABLE table_name ADD PRIMARY KEY (column_name);

## 移除主键
ALTER TABLE table_name DROP PRIMARY KEY

1.2、唯一索引

        数据库可以存在多个唯一索引,但是设置唯一索引列值唯一不重复。它可以作用单列,也可以作用于多列(多列值组合起来唯一)。

        语法:

## index_name 索引名称
## table_name 数据表名
## column 列
## 作用于单列
create unique index index_name on table_name(column);
## 作用域多列
create unique index index_name on table_name(column1, column2,...);

## 移除唯一索引
alter table table_name drop key index_name;

        例如:用户id单列唯一,姓名+手机号 联合唯一

1.3、普通索引

        普通索引是数据库表中一列或多列的值的集合,这些值按照一定的顺序存储,以便于快速查找和访问。

        语法:

## index_name 索引名称
## table_name 数据表名
## column 列
## 作用于单列
create index index_name on table_name(column);
## 作用于多列
create index index_name on table_name(column1,column2);

1.4、全文索引

        全文索引(Full-Text Index)是一种特殊的数据库索引,它允许用户对文本中的单词或短语进行搜索。这种索引专门用于存储、检索和管理大型文本数据,使得在包含大量文本的列中进行搜索变得更加高效。

        语法:

## table_name 表名
## index_name 索引名称
## column_name 字段名
ALTER TABLE table_name ADD FULLTEXT(index_name) (column_name);

2、索引数据结构

2.1、前序

        在探讨索引数据结构之前,大家也听说过B+Tree是索引数据结构,但是为什么要选择B+Tree结构呢,而不选择 常规的红黑树,Hash表呢。

        我们先从二叉树来看,请看下图:

        这个二叉树是我们理想中的情况,但是如果是按照顺序插入数据,二叉树有变成什么样了。

        图中可看到,竟然变成了链表结构,我们都知道链表结构的查询性能是很低的,最坏的是o(n),这个肯定无法满足索引结构,有一定风险。

        为了解决二叉树的顺序插入的缺点,二叉树又提出来红黑树,我们来看看它是什么样的。

        数据插入顺序(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),可以看出红黑树就解决了二叉树顺序查询变成链表的问题,这也是Java中Hash表底层结构会变成数组+链表+红黑树的原因。

         既然红黑树能满足了,但是InnoDB引擎为啥没有选择它也,其他红黑树本身还存在一个问题,当数据存量达到100w时,红黑树的高度与层级就变得很大,不利于查询,对于数据库这种高效查询场景是不适合的。

        我们看到红黑树能满足顺序存储问题,但是又把深度加大了,那我们何不在保持树特性时,减少深度也,不就解决这个问题了,是的,这就是后续的B-Tree结构了。

        B-Tree结构又是什么样的呢。我们先了解哈B-Tree的高度是什么,高度并不是我们理解的层高,而是一个节点可以存放几个子节点,一个节点可以存放 n-1个数据。例如:高度为5,一个节点的子节点就有5个(相当于一个节点的指针有5个),一个节点可以存放4个值,如果有疑问,可以看看下面的图。

        图中可知:一个节点存放多个值,一个节点多个子节点,这样就解决了红黑树深度问题。既然解决了为啥没有选择呢,我们从排序方面来思考,上图的叶子节点中可以看出是一个顺序的,但是又缺少了值,如 1,2,4,5,7,8中缺少了3,6两个值,如果采用它那是不是在排序的时候还需再去拿去一次,这样对性能不就降低了。、

        所以为了解决这个问题 就将B-Tree优化成立B+Tree树,同时将叶子节点之间以指针关联,做到可以访问后续数据的目的,下面我们来看看图:

        图中可知:叶子节点包含了上级节点所有的数据,并将相邻节点连接起来,达到快速访问目的。

         可以看出B+Tree结构满足需求,这也是InnoDB选择B+Tree结构的原因。InnoDB并不是这届这么使用的,它优化了叶子节点的关系,优化成立双向循环链表,同时将数据存放在里面,这也是我们常说的Mysql数据页。

        看到这大家对整个思路有了一定的认识,既然树可以实现,那为啥Hash表不可以呢。Hash的查询性能优于Tree查询性能的,其实这个本质上还是Hash表的缺陷造成的,如果Hash值没有冲突,那绝对是YYDS,但是一个冲突了就麻烦了(虽然业内提出来链地址法,开放寻址法等来解决)最终还是有些影响。其次冲突是一个原因,最核心的原因是Hash只能等值查询,范围查询不支持了,这才是没有选择的最终原因,排序这些本身还可以处理,范围不支持就不行了。

        Hash表缺点如下:1)Hash冲突。2)不支持范围查询。 

2.2、数据结构

        InnoDB索引分为 聚集索引 与 非聚集索引(二级索引)两种,他们之间的结构基本一致,只是叶子节点有点不一样。

        聚集索引:聚集索引可以看作是一个主键索引,一张表只有一个,生成策略可以查看主键索引。

        非聚集索引(二级索引):可以看作是一个索引之外的都是非聚集索引。

2.2.1、聚集索引

2.2.1、非聚集索引(二级索引)

2.2.2、总结

        上面两图可知:聚集索引与非聚集索引基本一致,除也叶子节点外的结构不一致外,其他的也差不多。 

        非聚集索引叶子节点之所以不存储Row数据,第一个原因:冗余存储,需要维护更多的数据,不利于数据库性能。第二个原因:节约内存。

3、索引的优缺点

        优点:提高检索速度,加速排序(索引本身有序),提高分组效率,减少磁盘IO(全命中索引)。

        缺点:占用磁盘空间,维护成本高,增加DML和DDl语句开销,创建和摧毁耗时等。

        总结:一般对常用查询字段添加索引,对经常更新字段不做索引,避免增加索引开销。

4、案例分析

        注意:索引不会讲解SQL如何优化,只会对比性能,相关优化点会在SQL优化中统一讲解。

4.1、主键索引认证

4.1.1、不使用主键索引查询

(1)查询id=100000的用户信息,图中可看到根据id等值查询竟然需要将近2秒时间。

4.1.2、使用主键索引查询

(1)创建主键索引列

## 创建主键索引
alter table d_user add primary key idx_primary_id(id);

 (2)查询id=100000的用户信息

        图中可知:耗时基本可以忽略不记,所以使用索引查询时会极大提高查询性能。

4.1.3、总结

        对比上诉两图中可知:b场景执行效率 > a场景执行效率

4.2、唯一索引认证

4.2.1、不使用唯一索引

(1)新增/更新数据场景:允许列有相同数据内容。

(2)查询phone='13500003162'用户信息,图中可知耗时2s

4.2.2、使用唯一索引

(0)phone列创建唯一索引

        注意随着数据越多,创建/更新/移除索引都需要耗更多时间。

create unique index idx_unique_phone on d_user(phone);

 

(1)新增/更新数据场景:不允许列有相同数据内容。

(2)查询phone=’13500003162‘用户信息

        注意:explain 命令在SQL优化中描述。

4.2.3、总结

       添加唯一索引列不允许有重复值,且作为条件查询时,提升性能。如果是单列则整列唯一,如果是多列唯一,则多列值整合在一起唯一。

4.3、普通索引认证

        图中可值:目前姓名与年龄都没有创建索引。

4.3.1、不使用普通索引查询

(1)查询name=测试名称480919 用户信息,耗时2秒多

4.3.2、使用普通索引查询

(0)姓名创建普通联合索引

create index idx_user_name on d_user(user_name);

 

(1)查询name=测试名称480919 用户信息

4.3.3、总结

        使用普通索引查询时,能极大提升查询性能。

4.4、全文索引认证

        全文索引在Mysql中很少使用,一般使用ES替代,所以不在展示。

5、SQL优化

        待定!!!

标签:index,name,##,查询,索引,Mysql,主键
From: https://blog.csdn.net/2401_85207246/article/details/144500792

相关文章

  • MySQL主从架构
    MySQL主从架构MySQL主从架构(Master-SlaveArchitecture)是一种常见的数据库高可用性和负载均衡的设计模式,通常用于提高系统的可伸缩性和可靠性。它基于数据复制(replication)机制,其中“主”服务器负责处理所有的写操作,而“从”服务器则通过复制主服务器的数据来保持数据一致性,主要用......
  • MySQL集群MHA
    MySQL集群MHAMHA由两部分构成:MHAManager(管理节点)和MHANode(数据节点)。在主从复制的MySQL集群中,MHAManager负责监控主节点的健康状况,当主节点出现故障时,MHAManager会自动选举出一个从节点升级为主节点,并协调其余从节点重新连接至新的主节点,实现无缝的故障转移。监控与故障检测......
  • MySQL集群mgr
    MySQL集群mgrMySQL集群MGR和MHA的区别MySQLManager(mysqlmgr)适用场景:用于需要高可用性、自动化管理和负载均衡的MySQL集群环境。适合部署基于GroupReplication的InnoDB集群。MHA(MySQLHighAvailability)适用场景:适用于传统的基于主从复制的MySQL环境。需......
  • MySQL_network
    MySQLRDBMS术语数据库:数据库是一些关联表的集合数据表:表是数据的矩阵列:一列包含了相同类型的数据行:一行一组相关的数据冗余:存储两倍数据主键:主键是唯一的,可以用主键来查询数据外键:外键用于关联两个表复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引......
  • 基于python+Django+mysql校园二手书籍交易平台系统设计与实现
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩,提供核心代码讲解,答辩指导。项目配有对应开发......
  • MYSQL访问控制,第2阶段:请求验证
    服务器接受连接后,进入权限控制的第二阶段。对于您通过连接发出的每个请求,服务器确定您要执行的操作,然后检查您的权限是否足够。这是授权表中的权限列发挥作用的地方。这些权限来自系统表user、global_grants、db、tables_priv、columns_priv或procs_priv。user表和global_gran......
  • MySql B树 B+树
    什么是叶子节点?想象你有一本书,书中的每一页都是一个节点。在这本书里,有些页面包含的是目录或章节标题(这些可以类比为内部节点),而另一些页面则包含了实际的内容,比如故事、文章或者数据记录(这些是叶子节点)。叶子节点就是存储真实数据的最终位置,在树结构中它们位于最底层,没有子节......
  • MySQL安装配置教程(非常详细),从零基础入门到精通,看完这一篇就够了
    Windows下有两种安装MySQL的方式:图形界面安装(.msi文件)免安装版(.zip压缩文件)MySQL下载官网:http://www.mysql.com也可前往百度网盘提取(两种安装方式文件都有):链接:https://pan.baidu.com/s/1NMRUu_E098h4ErzSXTUKgA提取码:3tfb一、MySQL免安装版配置教程http://c.bianche......
  • MySQL General error: 1364 Field 'XXX' doesn't have a default value
    向数据库中插入数据时报了以上错误,其原因为:MySQL使用了严格验证方式解决办法mysql设置的问题,有my.ini的就找这个文件,没有的就找my.cnf(这个一般都在/ect/my.conf)直接把[mysqld]模块下的sql-mode模式改变下,找到sql-mode,然后把这句删掉,改成:sql_mode=NO_ENGINE_SUBSTITU......
  • mysql 一个字段多种排序方式
    一、mysql一个字段多种排序数据idname1tkj1000020-1.11test2tkj1000020-13tkj1000020-2.1test4tkj1000020-2.2test5tkj1000020-26tkj1000020.1test7tkj1000020.1test_0018tkj1000020.2test9tkj1000020.3test10tkj1000020aest......