[mysql基础文档]-22-如何创建索引
引言
MySQL中的索引就是一个高效组织的数据结构,能够提高数据检索的速度。
文章目录
0×1.MySQL索引简介
索引的存放位置,对于Innodb储存引擎的表,索引会根据MySQL配置,集中存放在一个文件中,前面已经介绍过,而对于Myisam储存引擎的表,索引信息单独储存在表的.MYI文件中;
Index文件中不仅仅储存了要查询的数据的索引值,在索引值的下面还有这个索引所对应数据的指针信息,指向数据库文件真实数据位置,简单的说,索引就相当于书本的目录章节和对应页码,数据库可以根据章节标题和页码寻找对应数据,加快查询速度;
MySQL有以下几种常用索引:
普通索引
主键索引
唯一索引
全文索引
多列索引
一般将索引添加在查询频繁且重复度低的列上,实际上主键索引和唯一索引就是本系列文章前面所介绍的"主键约束"和"Unique约束",这两种约束就是两种特殊索引。
0×2.索引实例
a.普通索引
创建普通索引:
--在所有列声明后面,添加"key 索引名称(要索引的列名称)",一般索引名称和被索引的列名称相同即可 mysql> create table t52(id int,tx text,key id(id)); --将id列设置成主键索引,将tx列设置成普通索引并设置索引长度,tx(6)表示只取tx字段前六个字符成为索引依据(相当于一本书的目录,而目录每一行标题都只有六个字后面是对应页码) mysql> create table t54(id int primary key,tx text,key tx(tx(6))); --普通索引在表结构中Key字段是MUL,主键不用多说自然是PRI了 mysql> desc t54; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | tx | text | YES | MUL | NULL | | +-------+---------+------+-----+---------+-------+
b.主键索引
主键索引又叫"主键约束",前面的文章都有详细说明,实例:
--将id列设置为主键索引列,两种写法都可以 mysql> create table t54(id int,tx text,primary key(id)); --或 mysql> create table t54(id int primary key,tx text);
c.唯一索引
唯一索引又叫"Unique约束"前面已经详细介绍过,实例:
--将id列设置为唯一索引列,两种写法都可以 mysql> create table t55(id int,tx text,unique key(id)); --或 mysql> create table t55(id int unique key,tx text);
d.全文索引
全文索引只对使用空格分隔字符的语言环境有效,比如英文是一条句子中每个单词中间有空格,而中文字符之间是没有空格的,另外,全文索引在MySQL5.6.4之前的版本中,只有Myisam引擎的表才能支持全文索引,但MySQL5.6.10版本后,InnoDB也能支持这种索引技术了,请看下面的实例:
--显示当前的MySQL版本 mysql> select version(); +-------------------------+ | version() | +-------------------------+ | 5.5.43-0ubuntu0.14.04.1 | +-------------------------+ --因为本地的版本低于5.6.4,所以只好在创建表的时候指定Myisam引擎,否则是不能使用fulltext参数的,全文索引的添加与普通索引语法没什么区别 mysql> create table t56(id int primary key,tx text,fulltext key tx(tx)) engine=myisam; mysql> desc t56; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | tx | text | YES | MUL | NULL | | +-------+---------+------+-----+---------+-------+
e.多列索引
时候需要将数据分开储存便于管理,但有时候又需要将他们看成一个整体索引查询,这个时候就可以使用多列索引:
--创建多列索引,在所有列声明的最后使用"key 多列索引自定义名称(索引列1,索引列2,....)",用逗号分隔需要一起索引的全部列 mysql> create table t57(firstname varchar(100),lastname varchar(100),key fandl(firstname,lastname)); --插入两条记录 mysql> insert into t57 values('www.qingsword.com','qingsword'); mysql> insert into t57 values('qingsword.com','qingsword'); --使用explain查看后面的select语句使用了哪些索引,explain也可以测试上面的普通索引等,看索引到底有没有被数据库用上,possible_keys和key说明这条查询语句用上了我们上面创建的fandl多列索引 mysql> explain select * from t57 where firstname='qingsword.com' and lastname='qingsword' \G ************* 1. row ************* id: 1 select_type: SIMPLE table: t57 type: ref possible_keys: fandl key: fandl key_len: 606 ref: const,const rows: 1 Extra: Using where; Using index
不论查找过程中列名称如何前后排序,MySQL都能正确的组合,并且使用到正确的索引,前提是多列索引中位于开头的那些数据要包含在其中;假设有三段数据a,b,c都加入了多列索引(key keyName(a,b,c)),而我们仅仅b and c就不会主动去使用多列索引,但我们只要包含a,不论后面是c还是b,或仅仅只有a,都能主动使用多列索引查询;
这就是数据库中"左前缀"的概念,比如有一段数据‘ABCDEF’加入了索引,现在我们查询前面ABC这一部分,数据库可以根据索引去查找ABC开头的数据,但是我只知道DEF这一部分,数据库就不会主动使用索引去查找,因为索引中没有DEF开头的数据。
--仅使用多列索引后面的部分查询,并没有包含"左前缀" mysql> explain select * from t57 where lastname='qingsword' \G ************* 1. row ************* id: 1 select_type: SIMPLE table: t57 type: index possible_keys: NULL --显示没有可用的索引 key: fandl --那么这里为什么会显示用到了索引呢?数据库中有个概念叫做"索引覆盖",当被查询的列的值被包含在某个索引中时,数据库会根据这个包含关系找到对应的那个索引,再根据那个索引去找数据,类似于一个被动索引查找的过程,并非一开始就使用索引去查找。 mysql> explain select * from t57 where firstname='qingsword.com' \G ************* 1. row ************* possible_keys: fandl --使用"左前缀"查找,会主动去使用索引 key: fandl mysql> explain select * from t57 where lastname='qingsword' and firstname='qingsword.com' \G ************* 1. row ************* possible_keys: fandl --只要where中包含"左前缀"数据,and前后的位置并不会影响主动使用索引查找 key: fandl
0×3.索引管理
● 查看表索引信息
--查看上面创建的t56表的索引 mysql> show index from t56 \G ************* 1. row ************* Table: t56 Non_unique: 0 Key_name: PRIMARY --id列,主键索引 ************* 1. row ************* Table: t56 Non_unique: 1 Key_name: tx Seq_in_index: 1 Column_name: tx Index_type: FULLTEXT--tx列,多列索引
● 删除表索引信息
--删除普通索引和多列索引以及全文索引都可以使用下面两种方法 --方法一 --语法:drop index 索引名称 on 表名称; mysql> drop index tx on t56; --方法二 --语法:alter table 表名称 drop index 索引名称; mysql> alter table t52 drop index id; --主键索引和唯一索引删除方法相同,以主键索引为例 --语法:alter table 表名称 drop [primary key|unique key]; mysql> alter table t56 drop primary key;
● 追加索引信息
--给t52表id列再次添加上普通索引 mysql> alter table t52 add key id(id); --或,效果同上 mysql> alter table t52 add index id(id); --给t56表添加主键索引 mysql> alter table t56 add primary key(id); --或添加唯一索引 mysql> alter table t56 add unique key(id); --多列索引添加语法 mysql> alter table 表名称 add key(列1,列2,列3,...); --全文索引添加语法 mysql> alter table 表名称 add fulltext key(列名称);