您的位置:首页 > 数据库 > MySQL

mysql索引学习

2016-05-19 08:57 369 查看
索引用于快速找出在某列中有一特定值的行

如果不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行。

表越大,查询数据所花费的时间越多。

如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜寻数据文件,而不必查看所有的数据。

主要内容:

一、什么是索引?

二、索引的含义和特点

三、索引的分类

四、索引的设计原则

五、如何创建索引

六、删除索引

一、什么是索引?

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可提高数据库中特定数据的查询速度。

二、索引的含义和特点

索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用的指针。使用索引用于快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

例如:数据库中有2万条记录,现在要执行这样一个查询:select * from table where num=10000。如果没有索引,必须遍历整个表,直到num等于10000的这一行被找到为止;如果在num列上创建索引,MySQL不需要任何扫描,直接在索引里面找10000,就可以得知这一行的位置。可以,创建索引可以提高数据库的查询速度。

索引是在存储引擎中实现的,因此每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有的索引类型。根据存储引擎定义每个表的最大索引数和最大索引长度。所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节。大多数存储引擎有更高的限制。MySQL中索引的存储类型有两种:BTREE和HASH,具体和表的存储引擎相关。

引擎的优点主要有以下几条:

通过创建唯一索引,可以保证数据库表中的每一行数据的唯一性。

可以大大加快数据的查询速度,这也是创建索引的最主要的原因。

在实现数据的参考完整性方面,可以加快表和表之间的连接。

在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。

增加索引也有许多不利的方面:

创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。

索引需要占磁盘空间,除了数据表占据数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大尺寸。

当对表中的数据进行增加、删除和修改的时候,索引也要动态维护,这样就降低了数据的维护速度。

三、索引的分类

普通索引唯一索引

普通索引和唯一索引是MySQL中的基本索引类型,允许定义索引的列中插入重复值和空值。

唯一索引,索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

主键索引是一种特殊的唯一索引,不允许有空值。

单列索引组合索引

单列索引即一个索引只包含单个列,一个表上可以有多个单列索引。

组合索引指在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合。

全文索引

全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。MySQL只有MyISAM存储引擎支持全文索引。

空间索引

空间索引是对空间数据类型的字段建立索引,MySQL中的空间数据类型有4种,分别是:GEOMETRY、POINT、LINESTRING和POLYGON。MySQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类似的语法创建空间索引。创建空间索引的列必须声明为NOT NULL,空间索引只能在存储引擎为MyISAM的表的中创建。

四、索引的设计原则

索引设计不合理或者缺少索引都会对数据库和应用程序的性能造成障碍。

索引并非越多越好。表中如有大量索引,不仅占用磁盘空间,还会影响INSERT、DELETE、UPDATE等语句的性能,因为当表中的数据更改的同时,索引也会进行调整和更新。

避免对经常更新的表进行过多的索引,并且索引中的列尽可能少。而对于经常用于查询的字段应该创建索引,但要避免添加不必要的字段。

数据量小的表最好不要使用索引,由于数据较少,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果。

在条件表达式中经常要用到不同值较多的列上建立索引,在不同值少的列上不要建立索引。性别字段上只有男女两个不同值,就无须建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。

当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引需能确保定义的列的数据完整性,以提高查询速度。

在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

五、如何创建索引

MySQL支持多种方法在单个或多个列上创建索引:

<1> 在创建表的定义语句CREATE TABLE中指定索引列

<2> 使用ALTER TABLE语句在已存在的表上创建索引,

<3> 使用CREATE INDEX语句在已存在的表上添加索引。(问题来了,那么ALTER TABLE和CREAT INDEX加索引有什么区别呢?)

1. 创建表的时候创建索引

使用CREATE TABLE创建表时,除了可以定义列的数据类型,还可以定义主键约束、外键约束或者唯一性约束,而不论创建哪种约束,在定义约束的同时相当于在指定列上创建了一个索引

创建表时创建索引的基本语法如下:

CREATE TABLE table_name [col_name data_type]

[ UNIQUE | FULLTEXT | SAPTIAL ] [ INDEX | KEY ] [ index_name ] ( col_name[length] ) [ ASC | DESC ]

参数说明:

UNIQUE、FULLTEXT和SAPTIAL为可选参数,分别表示唯一索引、全文索引和空间索引;

INDEX与KEY为同义词,两者作用相同,用来指定创建索引;

col_name为需要创建索引的字段列,该列必须从数据表中定义的多个列中选择;

index_name指定索引的名称,为可选参数,如果不指定,MySQL默认col_name为索引值;

length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度;

ASC或DESC指定升序或者降序的索引值存储。

创建普通索引

最基本的索引类型,没有唯一性之类的限制,起作用只是加快对数据的访问速度。

create table book (
bookid  int not null,
bookname varchar(255) not null,
authors varchar(255) not null,
info varchar(255)  null,
comment varchar(255) null,
year_publication year not null,
index(year_publication)
);


SHOW CREAT TABLE查看表结构

用EXPLAIN查看索引是否正在使用:EXPLAIN SELECT * FROM book WHERE year_publication=1990\G

创建唯一索引

唯一索引与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值;如果是组合索引,则列值的组合必须唯一

create table t1 (
id int not null,
name char(30) not null,
unique index UniqIdx(id)
);


创建单列索引

单列索引是在数据表中的某一个字段上创建的索引,一个表中可以创建多个单列索引。前面两个例子都是单列索引。

create table t2 (
id int not null,
name char(50) null,
index SingleIdx(name(20))
);


创建组合索引

create table t3 (
id int not null,
name char(30) not null,
age int not null,
info varchar(255),
index MultiIdx(id, name, age(100))
);

组合索引可起几个索引的作用,但是使用时并不是随便查询哪个字段都可以使用索引,而是遵从”最左前缀“:利用索引中最左边的列集来匹配行,这样的列集称为最左前缀。例如这里由id、name和age3个字段构成的索引,索引行中按id/name/age的顺序存放,索引可以搜索下面的字段组合:(id, name, age)、(id, name)或者id。如果列构不成索引最左面的前缀,MySQL不能使用局部索引,如(age)或者(name, age)组合则不能使用索引查询。

创建全局索引

FULLTEXT全文索引可以用于全文搜索,只有MyISAM存储引擎支持FULLTEXT索引,并且只为CHAR、VARCHAR和TEXT列。索引总是对整个列进行,不支持局部(前缀)索引。

create table t4 (
id int not null,
name char(30) not null,
age int not null,
info varchar(255),
FULLTEXT index FullTxtIdx(info)
) ENGINE=MyISAM;

在MySQL中默认存储引擎为InnoDB,在这里创建表时需要修改表的存储引擎为MyISAM,不然创建索引会出错。

创建空间索引

create table t5 (
g GEOMETRY not null,
SPATIAL index spatIdx(g)
) ENGINE=MyISAM;


2. 在已存在的表上创建索引

在已存在的表中创建索引,可以使用ALTER TABLE语句或者CREATE INDEX语句。

使用ALTER TABLE语句创建索引

ALTER TABLE table_name ADD [ UNIQUE | FULLTEXT | SPATIAL ] [ INDEX | KEY ]

[ index_name ] (col_name[length], ...) [ ASC | DESC ]

在book表的name字段上建立索引

ALTER TABLE book ADD INDEX BkNameIdx( bookname(30) ); # 添加索引的时候为什么要指定列的长度嘞?在建表的时候不是已经为列指定了长度咩?

SHOW INDEX FROM book\G

ALTER TABLE book ADD UNIQUE INDEX UniqidIdx(bookId);

在book表的comment字段上建立单列索引

ALTER TABLE book ADD INDEX BkcmtIdx(comment(50));

语句执行之后会在book表的comment字段上建立名称为BkcmgIdx的索引,长度为50,在查询时只需要检索前50个字符。

在book表的authors 和info字段上建立组合索引

ALTER TABLE book ADD INDEX BkAuAndInfoIdx(author(20), info(50));

先创建表6,然后在上面创建全局索引

create table t6 (
id int not null,
info char(255)
) ENGINE=MyISAM;

注意修改ENGINE参数为MyISAM,MySQL默认引擎不支持全文索引。

ALTER TABLE t6 ADD FULLTEXT INDEX infoFTIdx(info);

创建空间索引

create table t7 (
g GEOMETRY not null
) ENGINE=MyISAM;

ALTER TABLE t7 ADD SPATIAL INDEX spatIdx(g);

3. 使用CREATE INDEX创建索引

create index语句可以在已经存在的表上添加索引,MySQL中create index被映射到一个alter table语句上:

CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX index_name

ON table_name (col_name[length], ...) [ASC | DESC]

其实这两个在已有的表上创建的方式没啥差别。

create index BkNameIdx ON book(bookname);

create UNIQUE index UniqidIdx ON book (bookid);

create fulltext index on t6(info);

六、删除索引

MySQL中使用ALTER TABLE或者DROP INDEX语句删除索引,DROP INDEX被映射到ALTER TABLE语句中。

1. 使用ALTER TABLE删除索引

ALTER TABLE table_name DROP INDEX index_name;

alter table book drop index UniqidIdx;

添加了auto_increment约束字段的唯一索引不能被删除。

2. 使用DROP INDEX语句删除索引

DROP INDEX index_name ON table_name;

删除表中的列时,如果要删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: