解锁MySQL数据库索引走向数据优化第一步不再只会CRUD

点赞多大胆,就有多大产!有支持才有动力!微信搜索公众号【达摩克利斯之笔】获取更多资源,文末有二维码!

Github地址:https://github.com/stt0626/JavaGreat持续收录更新资料

前言

不管在学习数据库或者在面试时都会遇到索引这个玩意儿,对于数据库如何优化,都会想到加索引,在此我们就来说说到底什么是索引,怎么用,如何用好等!索引也是我们走向光头必不可少的一项技能!篇幅太长影响阅读,索引数据结构我们下片再介绍!会不多说直接开搞!

索引你做个自我介绍

各位看客老爷我是索引,我其实很简单不像外边的妖艳贱货那么复杂,官网上说老夫是存储引擎用于快速找到记录的一种数据结构,不通的存储引擎对索引的实现方式不同,一般存储在磁盘中,为了减少数据扫描的次数,将随机I/O转变为顺序I/O,帮助我们在分组、排序等操作时,避免使用临时表。比如新华字典,要去找一个字可以通过翻目录用偏旁,拼音等来找一个字,如果没有这个目录你就得一页一页去找,索引就是数据库性能调优的基础方式,常用于实现数据的快速检索,接下来我要给大家好好介绍一下索引。

MySql数据访问方式

在Mysql中通常有以下两种方式来检索一行数据,如以下数据表

id name age
1 石添添 18
2 石小添 19
3 石笑天 10
4 石小索 15
5 石小引 21
6 石以初 20

顺序访问

顺序访问是执行全表扫描,比如我们要检索age为15的用户,从头到尾逐行遍历,直到在无序的行数据中找到符合条件的目标数据。这种方式实现比较简单,但是当表中有大量数据的时候,效率非常低下。例如,在几千万条数据中查找少量的数据时,使用顺序访问方式将会遍历所有的数据,花费大量的时间,显然会影响数据库的处理性能!

索引访问

索引访问是通过遍历索引来直接访问表中记录行的方式。使用这种方式的前提是对表建立一个索引,在列上创建了索引之后,查找数据时可以直接根据该列上的索引找到对应记录行的位置,从而快捷地查找到数据。

例如:我们在age列上添加索引,数据库系统就建立了一张索引列到实际记录的映射表,当需要查找age为15的数据时,会先在age索引上找到该记录,然后通过映射表直接找到数据行,并且返回该行数据。因为扫描索引的速度一般远远大于扫描实际数据行的速度,所以采用索引的方式可以大大提高数据库的工作效率。

至此我们知道索引是一种数据结构,需要单独存放可以增快我们的查询效率,是数据库优化的一种基础而重要方案,数据库搜索数据顺序访问索引访问两种方式。

索引创建

MySql提供三种创建索引的方法,注意InnoDB引擎会自动在主键上添加索引

使用CREATE INDEX 语句

用于在表已存在添加索引

语法

CREATE INDEX <索引名> ON <表名> (<列名> [<长度>] [ ASC | DESC])

说明

  • 索引名:指定索引名。一个表可以创建多个索引,但每个索引名在表中唯一
  • 表名:指定在哪个表中创建索引
  • 列名:指定要创建索引的列名。通常可以考虑将查询语句中在 JOIN 子句和 WHERE 子句里经常出现的列作为索引列,可以是一列也可以是多列,一列的称之为单列索引,多列成为组合索引
  • 长度:可选项。指定使用列前的 length 个字符来创建索引。使用列的一部分创建索引有利于减小索引文件的大小,节省索引列所占的空间。在某些情况下,只能对列的前缀进行索引。索引列的长度有一个最大上限 255 个字节(MyISAM 和 InnoDB 表的最大上限为 1000 个字节),如果索引列的长度超过了这个上限,就只能用列的前缀进行索引。另外,BLOB 或 TEXT 类型的列也必须使用前缀索引
  • ASC | DESC:可选项。ASC指定索引按照升序来排列,DNSC指定索引按照降序来排列,默认为ASC

例子 

CREATE INDEX index_user_age ON tb_user(age);

使用CREATE TABLE 语句

用于在创建表(CREATE TABLE)时创建,在CREATE TABLE 语句下添加

语法

1、表示在创建新表的同时创建该表的索引

KEY | INDEX [<索引名>] [<索引类型>] (<列名>,…)

2、表示在创建新表的同时创建该表的唯一性索引

UNIQUE [ INDEX | KEY] [<索引名>] [<索引类型>] (<列名>,…)

例子

CREATE TABLE student(
id INT PRIMARY KEY,
`name` VARCHAR(10) NOT NULL,
class VARCHAR(10) NOT NULL,
INDEX(name) -- 在name列上创建索引
);

 使用 ALTER TABLE 语句

在使用 ALTER TABLE 语句修改表的同时,可以向已有的表添加索引。具体的做法是在 ALTER TABLE 语句中添加以下语法成分的某一项或几项

语法

1、在修改表的同时为该表添加索引

ADD INDEX [<索引名>] [<索引类型>] (<列名>,…)

2、在修改表的同时为该表添加唯一性索引

ADD UNIQUE [ INDEX | KEY] [<索引名>] [<索引类型>] (<列名>,…)

 例子

ALTER TABLE student ADD INDEX index_class (class);

查看索引

语句

SHOW INDEX FROM <表名> [ FROM <数据库名>]

例子

SHOW index FROM table_name;

 说明

  • 表名:查询索引的表名
  • 数据库名:要查询的表在哪个数据库,这个可以使用数据库名.表名替代
  • Table:表名
  • No_unique:用于显示该索引是否是唯一索引。若不是唯一索引,则该列的值显示为 1;若是唯一索引,则该列的值显示为 0
  • Key_name:索引的名称,不指定名称就是列名
  • Seq_in_index:索引中的列序列号,从1开始计数
  • Column_name:列名
  • Collation:显示列以何种顺序存储在索引中。在 MySQL 中,升序显示值“A”,若显示为 NULL,则表示无分类
  • Cardinality:显示索引中唯一值数目的估计值。基数根据被存储为整数的统计数据计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL 使用该索引的机会就越大
  • Sub_part:若列只是被部分编入索引,则为被编入索引的字符的数目。若整列被编入索引,则为 NULL
  • Packed:指示关键字如何被压缩。若没有被压缩,则为 NULL
  • Null:用于显示索引列中是否包含 NULL。若列含有 NULL,则显示为 YES
  • Index_type:显示索引使用的类型和方法(BTREE、FULLTEXT、HASH、RTREE)
  • Comment:显示评注
  • Index_comment:显示评注

删除索引

当老板不再用我的时候,可以使用 DROP INDEX 语句或 ALTER TABLE 语句来删除我!

删除

语法

DROP INDEX <索引名> ON <表名>
或者再ALTER TABLE语句后边添加
DROP INDEX index_name:表示删除名称为 index_name 的索引。

注意:如果删除的列是索引的组成部分,那么在删除该列时,也会将该列从索引中删除;如果组成索引的所有列都被删除,那么整个索引将被删除

例子

DROP INDEX name ON student;
或
ALTER TABLE student DROP INDEX index_class;

索引分类

根据索引的用途在逻辑上可以分为以下五种

普通索引

普通索引是最基本的索引类型,唯一任务是加快对数据的访问速度,没有任何限制。创建普通索引时,通常使用的关键字是 INDEX 或 KEY

唯一性索引

唯一性索引是不允许索引列具有相同索引值的索引。如果能确定某个数据列只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE 把它定义为一个唯一性索引。创建唯一性索引的目的往往不是为了提高访问速度,而是为了避免数据出现重复

主键索引

主键索引是一种唯一性索引,即不允许值重复或者值为空,并且每个表只能有一个主键。主键可以在创建表的时候指定,也可以通过修改表的方式添加,必须指定关键字 PRIMARY KEY,注意一张表只能有一个主键

空间索引

空间索引主要用于地理空间数据类型 GEOMETRY

全文索引

全文索引只能在 VARCHAR 或 TEXT 类型的列上创建,并且只能在 MyISAM 存储引擎

在实际使用中,索引通常被创建成单列索引组合索引

  • 单列索引就是索引只包含原表的一个列
  • 组合索引也称为复合索引或多列索引,相对于单列索引来说,组合索引是将原表的多个列共同组成一个索引

敲黑板:一个表可以有多个单列索引,但这些索引不是组合索引。一个组合索引实质上为表的查询提供了多个索引,以此来加快查询速度。比如,在一个表中创建了一个组合索引(c1,c2,c3),在实际查询中,系统用来实际加速的索引有三个:单个索引(c1)、双列索引(c1,c2)和多列索引(c1,c2,c3)

索引注意事项和使用原则

注意事项

创建索引虽然可以提升Mysql的查询性能,但是索引在使用的时候也不是为所欲为,越多越好,需要注意以下几点

  • 索引的创建和维护需要消耗时间,这个时间会随着数据量的增多而增加
  • 除了表中数据占用控件,索引也需要占用一定空间,如果要建立聚簇索引,那么需要的空间就会更大
  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度 

使用原则

  • 在经常需要搜索的列上建立索引,可以加快搜索的速度
  • 在作为主键的列上创建索引,强制该列的唯一性,并组织表中数据的排列结构,在InnoDB存储引擎,默认给主键添加索引
  • 在经常使用表连接的列上创建索引,这些列主要是一些外键,可以加快表连接的速度
  • 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,所以其指定的范围是连续的
  • 在经常需要排序的列上创建索引,因为索引已经排序,所以查询时可以利用索引的排序,加快排序查询
  • 在经常出现在WHERE子句中的列上添加索引,加快条件的判断速度

以下场景建议不要添加索引,添加了反而增加数据库的压力,产生负面影响

  • 对于那些在查询中很少使用或参考的列不应该创建索引。因为这些列很少使用到,所以有索引或者无索引并不能提高查询速度。相反,由于增加了索引,反而系统要去维护和存储,增大压力
  • 对于那些只有很少数据值的列也不应该创建索引。因为这些列的取值很少,例如用户表的爱好列。查询结果集的数据行占了表中数据行的很大比例,增加索引并不能明显加快检索速度
  • 对于那些定义为 TEXT、IMAGE 和 BIT 数据类型的列不应该创建索引。因为这些列的数据量要么相当大,要么取值很少
  • 当修改性能远远大于检索性能时,不应该创建索引。因为修改性能和检索性能是互相矛盾的。当创建索引时,会提高检索性能,降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引,就是表中某个字段经常修改不要添加索引,因为会动态维护!

未完待续......索引数据结构我们下篇见,关注微信公众号获取更多学习资料


路漫漫其修远兮,吾将上下而求索 

发布了27 篇原创文章 · 获赞 148 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36386908/article/details/104571358
今日推荐