MySQL 索引 介绍创建与删除
Posted 奋斗的蜗牛灬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 索引 介绍创建与删除相关的知识,希望对你有一定的参考价值。
前言
- 正常系统工作时会远远不断的往表中新增数据,对一些大型的网站,索引的作用很明显,mysql 索引的建立对于 MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
一、索引介绍
1.1 数据库索引的概念
- 索引是一个排序的列表,在这个列表中存储着 索引的值 和 包含这个值的数据所在行的物理地址。
- 使用索引后不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据,因此能加快数据库的查询速度。
- 索引就好比是一本书的目录,可以根据目录中的页码快速找到所需的内容。
- 索引是表中一列或者若干列值排序的方法。
- 建立索引的目的是 加快对表中记录的查找或排序。
- 需要额外的磁盘空间。
1.2 索引的作用
加快查询速度,对字段进行排序。
- 设置了合适的索引之后,数据库利用各种快速定位技术,能够大大 加快查询速度,这是创建所有的最主要的原因。
- 当表数据量很大 或 多表查询时,使用索引可以成千上万倍地提高查询速度。
- 可以降低数据库的IO成本,并且索引还可以降低数据库的排序成本。
- 通过创建唯一性索引,可以保证数据表中每一行数据的唯一性。
- 可以加快表与表之间的连接。
- 在使用分组和排序时,可大大减少分组和排序的时间。
索引的缺点:
- 索引需要占用额外的磁盘空间。
-
- 对于 MyISAM 引擎而言,索引文件和数据文件是分离保存的,索引文件用于保存数据记录的地址。
- 而 InnoDB 引擎的表数据文件本身就是索引文件。
- 在插入和修改数据时要花费更多的时间,因为索引也要随之变动。
1.2 创建索引的原则依据
索引随可以提升数据库查询的速度,但并不是任何情况下都适合创建索引。
因为索引本身会消耗系统资源,在有索引的情况下,数据库会先进行索引查询,然后定位到具体的数据行,如果索引使用不当,反而会增加数据库的负担。
- 表的 主键、外键必须有索引。因为主键具有唯一性,外键关联的是子表的主键,查询时可以快速定位。
- 重复性少的,有唯一键的。
- 记录数 超过300行的表 应该有索引。如果没有索引,需要把表遍历一遍,会严重影响数据库的性能。
- 经常 与其他表进行连接的表,在连接字段上应该建立索引。
- 唯一性太差的字段不适合建立索引。
- 更新太频繁地字段不适合创建索引。
- 经常出现在 where 子句中的字段,特别是大表的字段,应该建立索引。
- 需要 GROUP BY、ORDER BY 的字段;
- 索引应该建在选择性高的字段上。
- 索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引。
二、索引的分类和创建
准备表:创建一张表 member ,int 类型默认长度为11,即 int(11)
create table member (id int(10),name varchar(10),cardid int(18),phone int,address varchar(50),remark text);
INSERT INTO member VALUES (1,'dog',1001,7177,'无锡','二哈'),
(5,'cat',2003,4242,'南京','折耳'),
(2,'lion',4002,1524,'徐州','辛巴'),
(4,'mouse',3004,7857,'常州','杰瑞'),
(3,'bird',6001,4358,'淮安','猫头鹰');
2.1 普通索引(NORMAL)
- 最基本的索引类型,没有唯一性之类的限制。
2.1.1 直接创建索引
CREATE INDEX 索引名 ON 表名 (列名[(length)]);
#(列名(length)):length是可选项,表示建立索引的长度。如果忽略 length 的值,则使用整个列的值作为索引。
如果指定使用列前的 length 个字符来创建索引,这样有利于减小索引文件的大小。
#索引名建议以“_index”结尾。
例:
create index phone_index on member (phone);
show keys from member\\G;
2.1.2 修改表方式创建
ALTER TABLE 表名 ADD INDEX 索引名 (列名);
例:
ALTER TABLE member ADD INDEX id_index (id);
#查看表所有索引
SHOW KEYS FROM member\\G;
2.1.3 创建表的时候指定索引
CREATE TABLE 表名 ( 字段1 数据类型,字段2 数据类型[,...],INDEX 索引名 (列名));
例:
create table STUDENT(
id int(10) not null,
name varchar(20) not null,
INDEX id_index (id));
show keys from STUDENT\\G;
2.2 唯一索引(UNIQUE)
- 与普通索引类似,但区别是唯一索引列的每个值都唯一。唯一索引允许有空值(注意和主键不同)。如果是用组合索引创建,则列值的组合必须唯一。添加唯一键将自动创建唯一索引。
2.2.1 直接创建唯一索引
CREATE UNIQUE INDEX 索引名 ON 表名(列名);
例:
create unique index name_index on member(name);
create unique index id_index on member(id);
show keys from member\\G;
2.2.2 修改表方式创建
ALTER TABLE 表名 ADD UNIQUE 索引名 (列名);
例:
alter table member add unique name_index (name);
show keys from member\\G;
比如现在 name 字段有重复的值,此时给 name 创建唯一索引,会报错,去除重复再尝试就能创建
查看索引 show keys for member 或 在工具中查看:
2.2.3 创建表的时候指定
CREATE TABLE 表名 (字段1 数据类型,字段2 数据类型[,...],UNIQUE 索引名 (列名));
例:
create table test2(
id int(10) not null,
name varchar(20) not null,
unique id_index (id));
show keys from test2\\G;
2.3 主键索引
- 是一种特殊的唯一索引,必须指定为“PRIMARY KEY”。一个表只能有一个主键,不允许有空值。 添加主键将自动创建主键索引。
2.3.1 创建表的时候指定
CREATE TABLE 表名 ([...],PRIMARY KEY (列名));
例:
create table test_table(
id int(10) not null,
name varchar(20) not null,
primary key (id));
或
create table test_table2(id int(10) not null PRIMARY KEY,name varchar(20) not null);
show keys from test_table\\G;
show keys from test_table2\\G;
2.3.2 修改表方式创建
ALTER TABLE 表名 ADD PRIMARY KEY (列名);
例:
alter table member ADD PRIMARY KEY(id);
show keys from member\\G;
2.4 组合索引(单列索引与多列索引)
- 可以是单列上创建的索引,也可以是在多列上创建的索引。
- 需要满足最左原则,因为 select 语句的 where 条件是依次从左往右执行的,所以在使用 select 语句查询时 where 条件 使用的字段顺序必须和组合索引中的排序一致,否则索引将不会生效。
CREATE TABLE 表名 (
列名1 数据类型,
列名2 数据类型,
列名3 数据类型,
INDEX 索引名 (列名1,列名2,列名3));
查询时就需要这样查:SEELCT * FROM 表名 WHERE 列名1='...' AND 列名2='...' AND 列名3='...';
例:
CREATE TABLE test5 (
id int(10) not null,
name varchar(20) not null,
sex char(2) not null,
INDEX index_amd (id,name));
show keys from test5\\G;
insert into test5 values(1,'lbw','男');
select * from test5 where id=1 AND name='lbw';
使用 explain
可以查看一条 sql 的性能:
where 后面的条件必须从左到右才会使用 组合索引,其他条件不行。
2.5 全文索引 (FULLTEXT)
- 适合在进行 模糊查询 的时候使用,可用于在一篇文章中 检索文本信息。
- 在 MySQL5.6 版本以前的 FULLTEXT 索引,仅可用于 MyISAM 引擎;
- 在 5.6 版本之后 innodb 引擎也支持 FULLTEXT 索引。
- 全文索引可以在 CHAR、VARCHAR 或者 TEXT 类型的列上创建
- 每个表只允许有一个全文索引。
- 查询时 WHERE 条件中的 ANAINST 不支持部分字符串查询,只支持整个字符查询。
创建方式:
2.5.1 直接创建索引
CREATE FULLTEXT INDEX 索引名 ON 表名 (列名);
例:
CREATE FULLTEXT INDEX address_index ON member(address);
2.5.2 修改表方式创建
ALTER TABLE 表名 ADD FULLTEXT 索引名 (列名);
例:
ALTER TABLE member ADD FULLETXT address_index (address);
修改表方式创建 全文索引
2.5.3 创建表的时候指定索引
CREATE TABLE 表名 (字段1 数据类型[,...],FULLTEXT 索引名 (列名));
#字段的数据类型可以为 CHAR、VARCHAR 或者 TEXT
例:
create table FULLINDEX(
id int(10) not null,
name varchar(20) not null,
address varchar(50),
fulltext address_full(address));
INSERT INTO FULLINDEX VALUES ('1','user1','tiananmen');
INSERT INTO FULLINDEX VALUES ('2','user2','jinggangshan');
INSERT INTO FULLINDEX VALUES ('3','user3','xibaipo');
2.5.4 使用全文索引查询
SELECT * FROM 表名 WHERE MATCH(列名) AGAINST('查询内容');
例:
SELECT * FROM member WHERE MATCH(address) AGAINST('xuzhou');
查询
不支持中文是因为 /etc/my.cnf 中配置的字符集原因。
而且不支持部分字符串查询,只支持整个字符查询
三、查看索引信息
#两个命令查看的信息一样
SHOW INDEX FROM 表名;
或者
SHOW KEYS FROM 表名;
#------各字段的含义如下:
Table:表的名称。
Non_unique:如果索引不能包括重复词,则为 0;如果可以,则为 1。
Key_name:索引的名称。
Seq_in_index:索引中的列序号,从 1 开始。
Column_name:列名称。
Collation:列以什么方式存储在索引中。在 MySQL 中,有值‘A’(升序)或 NULL(无分类)。
Cardinality:索引中唯一值数目的估计值。
Sub_part:如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为 NULL。
Packed:指示关键字如何被压缩。如果没有被压缩,则为 NULL。
Null:如果列含有 NULL,则含有 YES。如果没有,则该列含有 NO。
Index_type:用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
Comment:备注。
四、删除索引
4.1 根据索引名直接删除索引
DROP INDEX 索引名 ON 表名;
例:
DROP INDEX name_index ON member;
4.2 修改表方式删除索引
ALTER TABLE 表名 DROP INDEX 索引名;
例:
ALTER TABLE member DROP INDEX address_index;
#删除主键索引
ALTER TABLE member DROP PRIMARY KEY;
总结
索引就是一个排序的列表,没有索引就要进行全表扫描,有索引就可以根据物理地址查询对应的数据。
索引的作用:
- 加快查询速度,对某些字段进行排序,节省分组排序时间,加快表与表之间的连接速度。
索引的缺点: - 如果在不适合建立索引的字段建立索引,还会加重数据库负载;
- 占用物理空间。
索引的分类:
- 普通索引
- 唯一索引
- 主键索引
- 全文索引
- 空间索引
以上是关于MySQL 索引 介绍创建与删除的主要内容,如果未能解决你的问题,请参考以下文章