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从入门到精通-清华大学出版社

相关推荐
vvvae123428 分钟前
分布式数据库
数据库
雪域迷影1 小时前
PostgreSQL Docker Error – 5432: 地址已被占用
数据库·docker·postgresql
bug菌¹2 小时前
滚雪球学Oracle[4.2讲]:PL/SQL基础语法
数据库·oracle
逸巽散人2 小时前
SQL基础教程
数据库·sql·oracle
月空MoonSky2 小时前
Oracle中TRUNC()函数详解
数据库·sql·oracle
momo小菜pa2 小时前
【MySQL 06】表的增删查改
数据库·mysql
向上的车轮3 小时前
Django学习笔记二:数据库操作详解
数据库·django
编程老船长3 小时前
第26章 Java操作Mongodb实现数据持久化
数据库·后端·mongodb
全栈师4 小时前
SQL Server中关于个性化需求批量删除表的做法
数据库·oracle
Data 3174 小时前
Hive数仓操作(十七)
大数据·数据库·数据仓库·hive·hadoop