MySQL----索引

本文介绍了MySQL索引的概念、类型,包括主键索引、唯一索引和普通索引,以及组合索引。详细讨论了Btree、Hash和全文索引的特性。还分析了索引的优缺点,指出在数据量少、频繁更新字段和很少使用的字段情况下不适合使用索引。文章探讨了如何优化索引,如使用短索引、避免全表扫描、注意类型匹配,并对比了聚集索引与非聚集索引的差异,强调了覆盖索引在提高查询性能上的作用。最后,提出了根据查询需求选择合适索引的建议。
摘要由CSDN通过智能技术生成

索引概念

是帮助Mysql高效获取数据的排好序的数据结构,索引存储在文件里,它包含着对数据表里所有记录的引用指针,通过索引可以快速定位数据,就好比书的目录,可以加快数据库查询速度(一般数据库默认会以主键生成索引)

索引类型

mysql的索引分为单列索引(主键索引,唯一索引,普通索引)和组合索引.

  • 主键索引(可以将其归为唯一索引,但是主键索引的列不能为NULL)。主键索引会自动创建。
  • 唯一索引:索引值要唯一

        CREATE UNIQUE INDEX IndexName ON `TableName`(`字段名`(length));

  • 普通索引:没有限制

       CREATE  INDEX IndexName ON `TableName`(`字段名`(length));

  • 组合索引:多个限制条件,相当于目录的多级查询,先找某一个再去找某一个

       CREATE INDEX IndexName On `TableName`(`字段名`(length),`字段名`(length),...);

       如果你建立了组合索引(name,age,sex),那么它实际包含的是3个索引 (name) (name,age)(name,age,sex)

        对于select * from tablename where age=15 不会用索引,因为没有age的索引,遵循最左前缀原则

ps:多个单列索引与单个组合索引的查询效果不同,执行查询时,只能用一个索引,会从多个索引中选择一个限制最严格的索引。

按照索引结构分类

  • Btree索引:Btree索引是最常使用的索引,默认的基本都是Btree索引
  • hash索引:MyISAM不支持hash索引,Innodb是自适应的,会根据表的使用情况自动为表生成哈希索引,不能人为干预是否在一张表中生成哈希索引
  • 全文索引:对于全文的一个索引,会分词等;生成全文索引非常耗时以及耗费硬盘,InnoDB并不支持全文索引

        create  fulltext  index  index-content  on article(content);

索引的优缺点

优点

  • 大大加快了数据的查询速度(因为其独特的数据结构B+树,减少了磁盘I/O,因此速度变快)
  • 加速了表和表之间的的连接
  • 降低了CPU的使用率(索引文件本身就时排好序的(B+树),那么查询排序时,可以直接使用,不再进行排序,也就降低了CPU的使用率)

缺点

  • 索引虽然加速了查询速度,但是降低了增删改的效率,因为还需要去修改索引结构
  • 建立索引有索引文件存在,占用磁盘空间

那些情况不适合用索引?

并不是所有场景使用索引都适合的,下列情况就是不适合使用索引

  • 数据量少的,因为创建和维护索引是很耗费时间的,对于数据量少的本身查询速度也不会很慢,没有必要创建索引,另外索引还需要占磁盘空间。
  • 频繁更新的字段,创建索引还需要更新索引
  • 很少使用的字段,没有必要为不用的字段去维护索引结构

MySQL索引的优化

  • 使用短索引

对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作

  • 索引不会包含有NULL值的列

只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL

  • like语句操作

like “%aaa%” 不会使用索引而like “aaa%”可以使用索引,既以%号或者_开头的情况不会使用索引

MySQL只对以下操作符才使用索引:<,<=,=,>,>=,between,in,以及不以通配符%或_开头的时候的like()。理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则不建议使用过多的索引。

  • 尽量的扩展索引,不要新建索引

比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

  • 索引列排序

MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

  • 注意类型匹配

如果有类型转换,可能不会使用索引,所以查询的时候注意类型匹配

  • 尽量选择区分度高的列作为索引

区分度表示字段不重复的比例,比例越大我们扫描的记录数越少。主键索引和唯一索引的区分度最大,比如我们会选择学号做索引,而不会选择性别来做索引

聚集索引与非聚集索引

对于MyISAM并不支持聚集索引,只支持非聚集索引;但是InnoDB支持聚集索引

每个MyISAM表存储三个文件在磁盘上,一个.FRM文件存储表格式,.MYD存放数据文件,.MYI存放索引文件;但是每个InnoDB表只有两个文件存储在磁盘上,一个.FRM文件存储表格式,另一个是.IBD文件是索引和数据存放在一起的。(因为聚集索引)

MySQL创建表时没有显示的定义主键时,他首先会判断表中是否有非空的整形唯一索引,如果有,则该列为主键。如果没有符合条件的则会自动创建一个6字节的主键(该主键是查不到的).

 

聚集索引:往往是以主键作为索引列的,但也不全是。聚集索引是将索引列与表的数据排列在一起,也即整个表变成了一个索引,一个表只能有一个聚集索引。

事实上,一个没加主键的表,它的数据无序的放置在磁盘存储器上,一行一行的排列的很整齐, 跟认知中的表很接近。但是如果给表上了主键,那么表在磁盘上的存储结构就由整齐排列的结构转变成了树状结构(B+),就是整个表就变成了一个索引。这就是所谓的聚集索引。这就是为什么一个表只能有一个主键, 一个表只能有一个聚集索引,因为主键的作用就是把表的数据格式转换成索引(B+)的格式放置。

非聚集索引:非聚集索引和聚集索引一样, 同样是采用B+树作为索引的数据结构。索引树结构中各节点的值来自于表中的索引字段(不包含表数据), 假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成,在数据改变时, DBMS需要一直维护索引结构的正确性。如果给表中多个字段加上索引 , 那么就会出现多个独立的索引结构,每个索引(非聚集索引)互相之间不存在关联。(一个表可以有多个非聚集索引)每次给字段建一个新索引, 字段中的数据就会被复制一份出来, 用于生成索引。 因此, 给表添加索引,会增加表的体积, 占用磁盘存储空间。

对于MyISAM不支持聚集索引,所以它的索引文件和数据文件是分离的,不论索引列是否是主键,都是非聚集索引,叶子节点存放的都是磁盘的文件指针,通过这个指针定位到数据文件中找到数据

但是对于InnoDB是支持聚集索引的,所以它的数据文件和索引文件在一起,对于它的非聚集索引其叶子存放的就不是文件指针,而是聚集索引的索引值(主键),那么就可以通过自身索引查找到聚集索引的索引值进而查找到数据。

非聚集索引和聚集索引的区别

 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值(或者文件指针) , 再使用主键的值(或文件指针)定位到数据。官方区别:聚集索引的逻辑顺序与表中的相应行的物理顺序一致(相当于字典,所以也就只有一个聚集索引),而非聚集索引索引的逻辑顺序与磁盘上行的物理存储顺序不同。

对于MyISAM不论以何种方式查询表,都是用的非聚集索引找到文件指针去定位数据

对于InnoDB不管以任何方式查询表, 最终都会利用主键通过聚集索引来定位到数据, 聚集索引(主键)是通往真实数据所在的唯一路径。

覆盖索引

对于InnoDB有一种例外可以不使用聚集索引就能查询出所需要的数据, 这种非主流的方法 称之为覆盖索引查询, 也就是平时所说的复合索引或者组合索引查询。 文章上面的内容已经指出, 当为字段建立索引以后, 字段中的内容会被同步到索引之中, 如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至索引之中。

通过非聚集索引index_birthday_and_name查找birthday等于1993的叶节点的内容,然而, 叶节点中除了有表主键ID的值以外, name字段的值也在里面, 因此不需要通过主键ID值的查找数据行的真实所在, 直接取得叶节点中name的值返回即可。 通过这种覆盖索引直接查找的方式, 可以省略不使用覆盖索引查找的后面两个步骤, 大大的提高了查询性能,即覆盖查询。

ps1:单列索引可以看作索引列为1的联合索引,实际上联合索引就是每个树节点有多个索引值,若在查找的时候匹配到某一个索引值不匹配,后续的则不需要再进行匹配。

ps2:除了覆盖查询,非聚集索引都是要靠聚集索引的,所以聚集索引速度比较快,可以直接定位数据

何时使用聚集索引或非聚集索引?

1:我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可(叶节点是链式的指针串起来的);而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。

2:另外一点,对于频繁更新或者修改的索引列,不适合用聚集索引,因为聚集索引需要按照顺序排列,一旦修改我们要去维护这个顺序,所以不适合用聚集索引,但是可以使用非聚集索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值