索引用于快速找出在某列中有一特定值的行。

如果不使用索引,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支持多种方法在单个或多个列上创建索引:

  • 在创建表的定义语句CREATE TABLE中指定索引列,
  • 使用ALTER TABLE语句在已存在的表上创建索引,
  • 使用CREATE INDEX语句在已存在的表上添加索引。(问题来了,那么ALTER TABLE和CREAT INDEX加索引有什么区别呢?)

创建表的时候创建索引

使用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;

在已存在的表上创建索引

在已存在的表中创建索引,可以使用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);

使用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;

删除表中的列时,如果要删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除。

mysql索引学习的更多相关文章

  1. Mysql索引学习笔记

    1.btree索引与hash索引 下列范围查询适用于 btree索引和hash索引: SELECT * FROM t1 WHERE key_col = 1 OR key_col IN (15,18,2 ...

  2. MySQL索引学习记录

    参考资料: http://blog.csdn.net/v_july_v/article/details/6530142http://blog.codinglabs.org/articles/theor ...

  3. mysql 索引学习--多条件等值查询,顺序不同也能应用联合索引啦

    以前学习这一块的时候,是说:假设建立了联合索引a+b,那么查询语句也一定要是这个顺序才能应用该索引. 那么实际是怎样呢,经过mysql这么多次版本升级,相信mysql已经给我们做了某些优化. 下面是我 ...

  4. ”MySQL索引“学习总结

    序 learn by doing 是最快的学习方式.在百度外卖研发中心,我每天工作接触数据库方面最多的就是"索引",另外面试官在面试时也一定会考察到索引. Part 1, Expl ...

  5. mysql索引学习----2----创建索引、修改索引、删除索引的命令语句

    查看表中已经存在 index:show index from table_name; 创建和删除索引索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER ...

  6. 4.直方图介绍和使用|MySQL索引学习

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 一.导读 二.步骤 2.1 SQL语句 2.2 直方图案例 2.3 查看直方图统计信息 2.3 直方图分类 2.4 ...

  7. 3.联合索引、覆盖索引及最左匹配原则|MySQL索引学习

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 导语 在数据检索的过程中,经常会有多个列的匹配需求,今天介绍下联合索引的使用以及最左匹配原则的案例. 最左匹配原则作用在联 ...

  8. MySQL数据库学习笔记(六)----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  9. Mysql数据库学习笔记之数据库索引(index)

    什么是索引: SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间. 聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物 ...

随机推荐

  1. 设计模式实例(Lua)笔记之四(Builder 模式)

    1.描写叙述:      又是一个周三,快要下班了,老大突然又拉住我,喜滋滋的告诉我"牛叉公司非常惬意我们做的模型,又签订了一个合同,把奔驰.宝马的车辆模型都交给我我们公司制作了,只是这次又 ...

  2. [置顶] CSS语言精粹

    本文主要是对CSS中一些比较重要的高级部分作了一些整理,这些内容也许不是经常使用,但是都很强大.本文将长期更新. 边框 CSS2.1 规定:元素的背景是内容.内边距和边框区的背景.设置背景颜色时是没有 ...

  3. zend studio 13.6.1 安装+破解+汉化

    zend studio 13.6.1 X64 安装+破解+汉化+补丁 一.下载相关文件 1.官网原版下载 : http://downloads.zend.com/studio-eclipse/13.6 ...

  4. C#应用视频教程3.3 Halcon+C#测试

    接下来我们考虑把Halcon的代码移植到C#程序上,首先找到halcon的dll(.NET类库有1.0,2.0,3.5的,如果你安装了更新版本的halcon则有更新的.NET类库,我们复制最新的dll ...

  5. 【转】TCP(协议号6)的方方面面

    转:http://blog.sina.com.cn/s/blog_6002b97001018fxh.html 第一:TCP连接的建立(也就是所谓的三次握手)过程. 第一次握手:建立连接时,客户端发送s ...

  6. cocos2d-x 源代码分析 : EventDispatcher、EventListener、Event 源代码分析 (新触摸机制,新的NotificationCenter机制)

    源代码版本号来自3.x,转载请注明 cocos2d-x 源代码分析总文件夹 http://blog.csdn.net/u011225840/article/details/31743129 1.继承结 ...

  7. MySQL-EXPLAIN用法详解

    今天做一个订单任务, 其中需要查有无此订单号信息, 由于订单号是个列表, 所以想检测下如下语句的性能(主要在LIMIT 1上) "订单号 IN (订单号列表)" LIMIT 1 然 ...

  8. sms_queue 短信队列

    git地址:https://github.com/Filix/sms_queue 简介 通过队列的方式发送短信,暂时实现了redis作为队列. 以实现的第三方短信服务: 百悟.漫道. 发送短信方,只需 ...

  9. android多线程进度条

    多线程实现更新android进度条. 实例教程,详细信息我已经注释   android多线程进度条   01package com.shougao.hello; 02 03import android ...

  10. Linux-软件包管理-rpm命令管理-查询

    rpm -q httpd 查看apache包是否已经安装 rpm -qa 查看所有已经安装的包rpm -qa | grep httpd 查询包含和apache关键字相关联的所有包信息 rpm -qi ...