目录
1.索引的概念
2.索引的优缺
2.1索引的优点:
2.2索引的缺点:
2.3索引的应用场景:
3.索引的种类
4.索引的使用
4.1建表时创建
4.2建表后创建:
4.3查看自己创建的索引:
4.4索引的删除:
4.5查看SQL语句对索引的使用情况(即查询SQL的查询执行计划QEP):
4.6各类索引的使用:
哥几个来学索引啦~~
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息。
通俗点的例子就是如果将数据库表看成是一本书,那么索引就是书的目录,我们可以根据目录来找到书中指定内容的位置。
我们可以对表中的一列或者多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
a.建立索引的列可以保证行的唯一性,生成唯一的行id。
b.建立索引可以快速定位,有效缩短数据的检索时间,对于提高数据库性能有很大的帮助。
c.建立索引可以加快表与表之间的连接。
d.为用来排序或者分组的字段添加索引可以加快排序和分组的顺序。
a.创建索引和维护索引需要时间成本,这个成本随着数据量的增大而加大。
b.创建索引和维护索引需要空间成本,每一条索引都要占据数据库和物理库存储空间,数据量越大,占用的空间也越大(数据表占据的是数据库的数据空间)。
c.会降低表的增、删、改的效率,因为每次增、删、改索引需要索引进行动态维护,导致时间变长。
要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
①数据量较大,且经常对这些列进行条件查询。
②该数据库表的插入操作,及对这些列的修改频率较低。
③索引会占用额外的磁盘空间。
满足以上条件时,考虑对表中的这些字段创建索引,可以提高效率。
反之,如果非条件查询列,或者需要经常进行插入、修改的操作,或者磁盘空间不足时,不考虑创建索引。
① 普通索引(单列索引):单列索引是最基本的索引,它没有任何限制。
② 复合索引(组合索引):复合索引是在多个字段上创建的索引。复合索引遵守“最左前缀”原则,即在查询条件中使用了复合索引的第一个字段,索引才会被使用。因此,在复合索引中索引列的顺序至关重要。
③ 唯一索引:唯一索引和普通索引类似,主要的区别在于,唯一索引限制列的值必须唯一,但允许存在空值(只允许存在一条空值)。
空值和NULL值其实是两个不同的概念,在MySQL中空值是不占用内存的,而NULL值是占用内存的~~
如果添加索引的列的值存在两个或两个以上的空值,则不能创建唯一性索引。(一般在创建表的时候,要自动设置唯一性索引,需要在字段上加not null)。
如果添加索引的列的值存在两个或两个以上的null值,还是可以创建唯一性索引,只是后面创建的数据不能再插入null值,并且严格意义上此列并不是唯一的,因为存在多个null值。
④ 主键索引:主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。
⑤ 全文索引
在一般情况下,模糊查询都是通过like的方式进行查询的。但是对于海量数据,这并不是一个好方法,在like“value%”可以使用索引,但是对于like“%value%”这样的方式,执行全表查询,如果是对于数据量小的表,不存在性能问题,但是对于海量数据,进行全表扫描的效率是非常低效的,索引like进行模糊查询性能很低。
这种情况下,需要考虑使用全文搜索的方式进行优化。全文搜索在MySQL中是一个fulltext类型索引,fulltext索引在MySQL5.6版本之后支持InnoDB,而之前的版本只支持MyISAM表。
全文索引主要用来查找文本中的关键字,而不是直接与索引中的值比较,fulltext索引和其他索引大不相同,它更像一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。目前只有char、varchar、text列上可以创建全文索引。
语法:
create table 表名(
字段名 数据类型[完整性的约束条件],
......,
[unique | fulltext | spatial] index | key
[索引名] (字段名1[(长度)] [asc | desc]) [using 索引方法]
);
说明:
unique:可选,表示索引为唯一性索引。
fulltext:可选,表示索引为全文索引。
spatial:可选,表示索引为空间索引。
index和key:用于指定字段为索引,两者选其一即可,作用是一样的。
索引名:可选,给创建的索引一个新名称。
字段名1:指定索引对应的字段的名称,该字段必须是前面定义好的字段。
长度:可选,指索引的长度,必须是字符串类型才可以使用。
ASC:可选,表示升序排列。
alter table 表名 add [unique | fulltext | spatial] index | key [索引名]
(字段名1[(长度)] [asc | desc]) [using 索引方法];
或者
create [unique | fulltext | spatial] index 索引名 on 表名(字段名) [using 索引方法];
show index from 表名;
drop index 索引 on 表名;
或者
alter table 表名 drop index 索引名
创建索引和删除索引都是十分危险的操作,如果针对的是一张数据量巨大的表创建索引,那么会导致创建索引的过程中产生大量的磁盘IO,此时主机可能直接就卡了。
在select语句前加explain即可:
explain select * from index_name where...
id:SELECT识别符。这是SELECT的查询序列号。
select_type:SELECT类型。
a.SIMPLE: 简单SELECT(不使用UNION或子查询)
b.PRIMARY: 最外面的SELECT
c.UNION:UNION中的第二个或后面的SELECT语句
d.DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
e.UNION RESULT:UNION的结果
f.SUBQUERY:子查询中的第一个SELECT
g.DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
h.DERIVED:导出表的SELECT(FROM子句的子查询)
table:表名
type:联接类型。
联接类型是SQL性能的非常重要的一个指标,结果值从好到坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL。
一般来说,得保证查询至少达到range级别。
possible_keys:possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
key:key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
key_len:key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。注意通过key_len值我们可以确定MySQL将实际使用一个多部关键字的几个部分。
ref:ref列显示使用哪个列或常数与key一起从表中选择行。
rows:rows列显示MySQL认为它执行查询时必须检查的行数。
Extra:该列包含MySQL解决查询的详细信息。
① 普通索引(单列索引)
(1)直接创建索引:
create index index_name on table_name(col_name1, col_name2 ...);
如果是多个列名,那么这几个列名的索引名相同。
(2)修改表结构的方式来添加索引
alter table table_name add index index_name(col_name1, col_name2 ...);
如果是多个列名,那么这几个列名的索引名相同。
(3)创建表时同时创建索引
create table table_name (
col_name1 ... ,
col_name2 ... ,
...,
index index_name(col_name(len))
);
比如:
create table student (
id int,
name varchar(20),
index id_name,
index name_index (name(20))
);
(4)删除索引
drop index index_name on table_name;
或者
alter table table_name drop index col_name;
使用情况:
1.只涉及到其中的一个字段时,都能使用到索引
2.涉及到多个索引字段时,如果这些索引字段中,存在主键索引,那么只会使用该索引(即:MYSQL优化器会选出并先执行最“严”的索引)
3.涉及到多个索引字段时,如果这些索引字段中,不存在主键索引的话,那么就会使用该使用的索引(注:如果通过其中的部分索引就能准确定位的话,那么其余的索引就不再被使用),先使用哪个索引,再使用哪个索引是由MySQL优化决定的。
4.当对索引字段进行 >, <,>=, <=,not in,between …… and ……,函数(索引字段),like模糊查询%在字段前时,不会使用该索引。
② 复合索引(组合索引)
(1)创建一个复合索引
create index index_name on table_name(col_name1, col_name2,...);
(2)修改表结构的方式添加索引
alter table table_name add index index_name (col_name1, col_name2,...);
使用情况:
1.假设组合索引为a,b,c,那么当SQL中对应有:(a) 或 (a,b) 或 (a,b,c) 的时候,可称为完全满足最左侧原则。
当SQL中查询条件只有(a,c)的时候,可称为部分满足最左原则。
当SQL中没有a的时候,可称为不满足最左侧原则,不满足最左侧原则不会使用索引。
2.从MySQL5.7开始,会自动优化,比如会把(c,b,a)优化为(a,b,c)使之完成满足最左原则,会把(c,a)优化为(a,c)使之部分满足最左原则。即:SQL中条件的先后顺序可以改变。
3.满足部分最左原则,只会走到最左边的索引,到右边的那个索引不会使用到。比如在执行:select * from table_name where a = ? and c = ?;时,到a字段会使用组合索引,到c字段就不会。
4.如果满足了最左原则,但是不满足“索引”自身的使用规范,那么组合索引走到这里之后,不会再往下走了。比如当对索引字段进行 >, <,>=, <=,not in,between …… and ……,函数(索引字段),like模糊查询%在字段前时,不会使用该索引。
③ 唯一索引
(1)直接创建唯一索引:
create unique index index_name on table_name(col_name1, col_name2 ...);
如果是多个列名,那么这几个列名的索引名相同。
(2)修改表结构的方式来添加唯一索引
alter table table_name add unique index index_name(col_name1, col_name2 ...);
如果是多个列名,那么这几个列名的索引名相同。
(3)创建表时同时创建唯一索引
create table table_name (
col_name1 ... ,
col_name2 ... ,
...,
unique index index_name(col_name(len))
);
④ 主键索引
(1)修改表结构的方式来添加主键索引
alter table table_name add parimary key (col_name);
如果是多个列名,那么这几个列名的索引名相同。
(2)创建表时同时创建主键索引
create table table_name (
col_name1 ... ,
col_name2 ... ,
...,
parimary key (col_name(len))
);
⑤ 全文索引
(1)直接创建全文索引:
create fulltext index index_name on table_name(col_name1, col_name2 ...);
如果是多个列名,那么这几个列名的索引名相同。
(2)修改表结构的方式来添加全文索引
alter table table_name add fulltext index index_name(col_name1, col_name2 ...);
如果是多个列名,那么这几个列名的索引名相同。
(3)创建表时同时创建全文索引
create table table_name (
col_name1 ... ,
col_name2 ... ,
...,
fulltext index_name(col_name(len))
);
以上就是MySQL索引的全部内容了,后续还有MySQL索引的实现原理哦~~
本篇部分摘自大佬文章:
(12条消息) Mysql索引整理总结_阿飞云的博客-CSDN博客
(12条消息) MySQL索引的创建与使用_mysql索引怎样创建_justry_deng的博客-CSDN博客