MySQL 索引

目录

一、索引概述

二、索引的优缺点

1、优点

2、缺点

三、索引的分类

1、普通索引和唯一索引

2、单列索引和组合索引

3、全文索引

4、空间索引

四、索引设计原则

五、创建索引

1、在创建表时创建索引

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

六、查看/删除索引

1、查看索引

2、删除索引

七、索引练习


一、索引概述

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

索引是在存储引擎中实现的,每种存储引擎的索引是不同的,并每种存储索引不一定支持全部索引。所有存储引擎至少支持16个索引,总索引长度至少为256字节。MySQL中索引的存储类型有两种:BTREE和HASH。MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY和HEAP存储引擎可以支持HASH和BTREE索引。

二、索引的优缺点

1、优点

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

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

3)在实现数据的参考完整性方面,可以加速表与表之间的连接速度。

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

2、缺点

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

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

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

三、索引的分类

1、普通索引和唯一索引

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

唯一索引定义列的值必须唯一,允许为空,主键索引是特殊的唯一索引,但是主键索引不允许有空值。

2、单列索引和组合索引

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

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

3、全文索引

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

4、空间索引

空间索引是对空间数据类型的字段建立的索引,MySQL的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。MySQL使用SPATIAL关字扩展,创建空间索引必须声明列为NOT NULL,只能创建在MyISAM存储引擎中。

四、索引设计原则

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

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

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

4)在不同值很少的列上不要建立索引,应该建在不同值较多的列上建立索引,这样才会加快查询速度。

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

6)在频繁进行排序或分组的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

五、创建索引

1、在创建表时创建索引

基本语法

sql 复制代码
create table 表名(
字段名1 数据类型 [约束条件等]
字段名2 数据类型 [约束条件等]
......
[unique|fulltext|spatial] [index|key] [索引名] [字段名 [长度] [ASC|DESC]]
);

unique---唯一索引;

fulltext---全文索引;

spatial---空间索引;

index|key---作用相同,用来创建的索引;

长度---只有字符串类型才可以指定索引的长度。

1)、创建普通索引

sql 复制代码
mysql> create table test_a(
id int not null,
name varchar(255),
age int,
index(id)
);
Query OK, 0 rows affected (0.01 sec)

2)、创建唯一索引

sql 复制代码
mysql> create table test_b( 
id int not null, 
name varchar(255), 
age int, 
unique index unique_index(id) 
);
Query OK, 0 rows affected (0.01 sec)

3)、创建单索引

sql 复制代码
mysql> create table test_c( 
id int not null, 
name varchar(255), 
age int,
index single_index(name) );
Query OK, 0 rows affected (0.01 sec)

4)、创建组合索引

sql 复制代码
mysql> create table test_d( 
id int not null, 
name varchar(255), 
age int,
index multi_index(id,name) );
Query OK, 0 rows affected (0.01 sec)

5)、创建全文索引

sql 复制代码
mysql> create table test_e( 
id int not null, 
name varchar(255), 
age int,
fulltext index fulltext_index(name) );
Query OK, 0 rows affected (0.13 sec)

6)、创建空间索引

sql 复制代码
mysql> create table test_f( 
id geometry not null, 
name varchar(255), 
age int,
spatial index spatial_index(id) )engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)

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

基本语法1

sql 复制代码
alter table 表名 add [unique | fulltext | spatial] 
[index | key] [索引名](字段名)[长度] [asc | desc];

基本语法2

sql 复制代码
create [unique | fulltext | spatial] index 索引名 
on 表名 (字段名[长度]) [ASC | DESC];

在添加时,定义给上面建表时创建类似。

六、查看/删除索引

1、查看索引

方法一:查询索引

sql 复制代码
show create table 表名 \G

例如

sql 复制代码
mysql> show create table test_a \G
*************************** 1. row ***************************
       Table: test_a
Create Table: CREATE TABLE `test_a` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

方法二:查询某张表中的索引情况

sql 复制代码
show index from 表名;

例如

sql 复制代码
mysql> show index from test_a;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_a |          1 | id       |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

方法三:查看使用计划查询SQL使用索引情况

sql 复制代码
explain select 字段列表 from 表名 [where <条件表达式>] \G

例如

sql 复制代码
mysql> explain select * from test_b where id=1 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test_b
   partitions: NULL
         type: const
possible_keys: unique_index
          key: unique_index
      key_len: 4
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

2、删除索引

语法1

sql 复制代码
drop index 索引名 on 表名

语法2

sql 复制代码
alter table 表名 drop index 索引名;

例如

sql 复制代码
#先查看表的索引
mysql> show index from test_a;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_a |          1 | id       |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
#删除指定索引
mysql> drop index id on test_a;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
#查看是否被删除
mysql> show index from test_a;
Empty set (0.00 sec)

七、索引练习

素材

sql 复制代码
	+------------+-------------+------+-----+---------+----------------+
	| Field      | Type        | Null | Key | Default | Extra          |
	+------------+-------------+------+-----+---------+----------------+
	| goods_id   | int(11)     | NO   | PRI | NULL    | auto_increment |
	| goods_name | varchar(20) | NO   |     |         |                |
	| cat_id     | int(11)     | NO   |     | 0       |                |
	| brand_id   | int(11)     | NO   |     | 0       |                |
	| goods_sn   | char(12)    | NO   |     |         |                |
	| shop_price | float(6,2)  | NO   |     | 0.00    |                |
	| goods_desc | text        | YES  |     | NULL    |                |
	+------------+-------------+------+-----+---------+----------------+
	
	+-----------+-------------+------+-----+---------+----------------+
	| Field     | Type        | Null | Key | Default | Extra          |
	+-----------+-------------+------+-----+---------+----------------+
	| cat_id    | int(11)     | NO   | PRI | NULL    | auto_increment |
	| cate_name | varchar(20) | NO   |     |         |                |
	| parent_id | int(11)     | NO   |     | 0       |                |
	+-----------+-------------+------+-----+---------+----------------+
	

1、建立一个utf8编码的数据库test1

sql 复制代码
mysql> create database test1 charset=utf8;
Query OK, 1 row affected (0.00 sec)

mysql> use test1;
Database changed

2、建立商品表goods和栏目表category

如上表结构创建表:存储引擎engine myisam 字符集charset utf8

sql 复制代码
mysql> create table goods( 
goods_id int(11) primary key auto_increment, 
goods_name varchar(20) not null, 
cat_id int(11) not null default 0, 
brand_id int(11) not null default 0, 
goods_sn char(12) not null, 
shop_price float(6,2) not null default 0.00, 
goods_desc text 
)engine=MyISAM,charset=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> create table category ( 
cat_id int(11) primary key auto_increment, 
cate_name varchar(20) not null, 
parent_id int not null default 0 
)engine=MyISAM,charset=utf8;
Query OK, 0 rows affected (0.00 sec)

3、在 goods_name 列上加唯一性索引(用alter table方式)

sql 复制代码
mysql> alter table goods add unique index unique_index(goods_name);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from goods;
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| goods |          0 | PRIMARY      |            1 | goods_id    | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| goods |          0 | unique_index |            1 | goods_name  | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)

4、在 shop_price 列上加普通索引(用create index方式)

sql 复制代码
mysql> create index shop_price_index on goods(shop_price);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from goods;
+-------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name         | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| goods |          0 | PRIMARY          |            1 | goods_id    | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| goods |          0 | unique_index     |            1 | goods_name  | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| goods |          1 | shop_price_index |            1 | shop_price  | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

5、在表category中cat_id上增加普通索引,然后再删除 (分别使用drop index和alter table删除)

sql 复制代码
#建立普通索引
mysql> alter table category add index index_cat_id(cat_id);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
#查看建立成功没有
mysql> show index from category;
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| category |          0 | PRIMARY      |            1 | cat_id      | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| category |          1 | index_cat_id |            1 | cat_id      | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
#使用drop index删除索引
mysql> drop index index_cat_id on category;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
#查看删除成功没有
mysql> show index from category;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| category |          0 | PRIMARY  |            1 | cat_id      | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
#再创建索引
mysql> alter table category add index index_cat_id(cat_id);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
#查看创建成功没有
mysql> show index from category;
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| category |          0 | PRIMARY      |            1 | cat_id      | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| category |          1 | index_cat_id |            1 | cat_id      | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
#使用alter table 删除索引
mysql> alter table category drop index index_cat_id;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
#查看删除成功没有
mysql> show index from category;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| category |          0 | PRIMARY  |            1 | cat_id      | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

参考书籍:MySQL5.7从入门到精通-清华大学出版社

相关推荐
PGCCC2 分钟前
【PGCCC】postgresql 缓存池并发设计
数据库·缓存·postgresql
小爬虫程序猿9 分钟前
如何利用Python解析API返回的数据结构?
数据结构·数据库·python
wowocpp1 小时前
查看 磁盘文件系统格式 linux ubuntu blkid ext4
linux·数据库·ubuntu
C吴新科4 小时前
MySQL入门操作详解
mysql
Ai 编码助手7 小时前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
陈燚_重生之又为程序员7 小时前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析
caridle7 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
白云如幻7 小时前
MySQL排序查询
数据库·mysql
萧鼎7 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
^velpro^7 小时前
数据库连接池的创建
java·开发语言·数据库