1 引言
在没有索引的情况下,如果要寻找特定行,数据库可能要遍历整个数据库,使用索引后,数据库可以根据索引找出这一行,极大提高查询效率。本文是对MySQL数据库中索引使用的总结。
2 索引简介
索引是一个单独的、存储自磁盘上的数据库结构,包含着对数据表里所有记录的引用指针。使用索引用于快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。
小时候我们都用过现代汉语词典,当我们要查找某个字时,如果没有目录,我们需要一页一页去寻找,有了目录,直接根据目录就可以找到那个字。数据库中的索引就相当于现代汉语词典中的目
录,目录中存放在一个指向内容真实地址的指针,可以提高我们查找的速度。
另外需要说明的是,索引是在存储引擎中实现的,因此,每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有的索引类型。MySQL中索引的存储类型有两种:BTREE和HASH,具体和表的存储引擎相关。MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。
索引的有点主要有一下几条:
(1)通过创建唯一索引,可以保证数据库中每一行数据的唯一性。
(2)可以大大加快数据的查询速度,这也是创建索引的最主要的原因。
(3)在实现数据的参考完整性方面,可以加速表和表之间的连接。
(4)在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。
当然,索引也有许多不利方面,主要表现在以下几个方面:
(1)创建索引和维护索引都要消耗时间,并且随着数据量的增加所耗费的时间也会增加。
(2)索引需要占用磁盘空间。
(3)对数据表进行增加、删除、修改时,索引也要动态维护,这样就降低了数据的维护速度。
3 索引的分类
MySQL的索引可以分为以下几类:
(1)普通索引和唯一索引
普通索引和唯一索引是根据索引的功能来划分。
普通索引是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值。
唯一索引的索引列的值必须唯一,但允许空值。如果是组合索引,则列的值组合必须唯一。主键索引是一种特殊的唯一索引,不允许有空值。
(2)单列索引和组合索引
事实上,单列索引和组合索引的划分是根据创建索引时所引用的列的数量来划分。
单列索引是只一个索引只包含单个列,一个表可以有多个单列索引。
组合索引指在表的多个字段组合上创建索引,但只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。
组合索引可以起到多个索引的作用,但是使用时并不是随便哪个字段都可以使用索引的,而是遵从“最左前缀”:利用索引中最左边的列集列匹配行,这样的列集称为最左前缀。例如由id、name、age这3个字段字段构成的索引,索引行中按id/name/age的顺序存放,索引可以搜索下面字段组合:(id, name , age)、(id , name)、(id)。如果不构成索引的最左边的前缀,MySQL不能使用局部索引,如(age)、(name, age)都不能使用索引进行查询。
(3)全文索引
全文索引类型为FULLTEXT,在定义索引的列上至此值需得全文查找,允许在这些索引列上插入空值和重复值。
(4)空间索引
很少用到,本文不涉及。
4 创建索引
创建索引的方式有三种:
(1)直接创建索引
语法结果如下:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name ON table_name (column(length),…) [ASC|DESC]
a. 创建普通索引
create index bknameIndex on book(bookname) ;
b. 创建唯一索引
create unique index unique_Index on book(bookId) ;
c. 创建单列索引
create index single_Index on book(comment(10)) ;
d. 创建多列索引
create index mutil_Index on book(authors(20) , info(20)) ;
e. 创建全文索引
create fulltext index fulltext_Index on book(info) ;
(2)通过修改表结构的方式添加索引
语法结构如下:
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] index_name (column(length),…) [ASC|DESC]
a. 创建普通索引
alter table book add index bkName(bookname(30)) ;
b. 创建唯一索引
alter table book add unique index uniqueIndex(bookId) ;
c. 创建单列索引
alter table book add index signalIndex2 on(comment(50)) ;
d. 创建多列索引
alter table book add index mutilIndex (authors(30) , info(50)) ;
e. 创建全文索引
alter table book add fulltext index fulltextIndex (info) ;
(3)创建表的时候同时创建索引
语法结构如下:
CREATE TABLE table_name (
……(创建字段和约束),
[UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [INDEX|KEY] [index_name] (col_name [length]) [ASC|DESC]
)
a. 创建普通索引
create table book( bookid int not null , bookname VARCHAR(255) not null , authors VARCHAR(255) not null , info VARCHAR(255) not null , comment VARCHAR(255) not null , year_publication YEAR not null , index pub_index(year_publication) );
b. 创建唯一索引
create table book( …… unique index pub_index(bookid) );
c. 创建单列索引
create table book( …… index single_index(authors) );
d. 多列索引
create table book( …… index mutil_index(bookid, authors) );
e. 创建全文索引
create table book( …… fulltext index fulltext_index(info) );
(注:MySQL5.7中默认存储引擎为InnoDB,在这里创建表时需要修改表的存储引擎为MyISAM,否则会出错)
5 删除索引
(1)使用ALTER TABLE删除索引
语法结构:
ALTER TABLE table_name DROP INDEX index_name ;
(注:有AUTO_INCREMENT约束的字段的唯一索引不能被删除)
示例:删除book表中名为fulltext_Index的索引
alter table book drop index fulltext_Index ;
(2)使用DROP INDEX语句删除索引
语法结构:
DROP INDEX index_name ON table_name ;
示例:删除book表中名为fulltext_Index的索引
drop index mutil_index on book ;
6 索引设计原则
索引设计不合理或者缺少索引都会对数据库性能造成不良影响。那么设计索引是该如何考虑呢?
(1)索引并非越多越好,一个表中如果有大量的索引,不仅占用磁盘空间,而且会影响INSERT、DELETE、UPDATE等语句的性能,因为当表中的数据更改的同时,索引也会进行调整和更新。
(2)数据量小的表最好不要使用索引,由于数据量较小,查询所花费的时间可能比表里索引的时间还要短,索引可能不会产生优化的效果。
(3)避免对经常更新的表进行过多的索引,并且索引中的列尽可能少。对经常用于查询的字段应该创建索引,但要避免添加不必要的字段。
(4)在条件表达式中经常用到的不同值较多的列上建立索引,在不同值很少的列(例如性别字段,只有男女两个取值)不要建立索引。
(5)当唯一性是数据本身的特征时,指定唯一索引,可确保数据完整性并提高查询速度。
(6)在频繁进行排序、分组的列上建立索引,如果排序的列有多个,可以在这些列上建立组合索引。
7 总结
本文从索引的概念入手,简单介绍了索引的特点和分类,并通过实例对创建和删除索引进行说明。索引是个好东西,但却并非多多益善,这一点在索引设计原则中有说到。