MySQL 案例实战--MySQL 索引

前言

本环境是基于 Centos 7.8 系统构建MySQL-5.7.14
具体构建,请参考 MySQL-5.7.14 环境构建

索引是一种特殊的数据库结构,可以用来快速查询数据库表中的特定记录。索引是提高数据库性能的重要方式。MySQL中,所有的数据类型都可以被索引。MySQL的索引包括普通索引、惟一性索引、全文索引、单列索引、多列索引和空间索引等。接下来,我将详细介绍MySQL的索引。


一、什么是索引

认识索引

模式(schema)中的一个数据库对象

  • 在数据库中用来加速对表的查询
  • 通过使用快速路径访问方法快速定位数据,减少了磁盘的I/O
  • 与表独立存放,但不能独立存在,必须属于某个表
  • 由数据库自动维护,表被删除时,该表上的索引自动被删除。
  • 索引的作用类似于书的目录,几乎没有一本书没有目录,因此几乎没有一张表没有索引。

索引的优缺点

创建索引的最主要的原因:

  • 索引的优点是可以提高检索数据的速度
  • 对于有依赖关系的子表和父表之间的联合查询时,可以提高查询速度
  • 使用分组和排序子句进行数据查询时,同样可以显著节省查询中分组和排序的时间。

索引的缺点:

  • 创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加
  • 索引需要占用物理空间,每一个索引要占一定的物理空间
  • 增加、删除和修改数据时,要动态的维护索引,造成数据的维护速度降低了。

MySQL的索引包括普通索引、惟一性索引、全文索引、单列索引、多列索引和空间索引。

二、索引的创建

1、通过创建表创建索引

# 创建普通索引
mysql> create table stu_name_index1
    -> (id int,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> index name_index(name));
Query OK, 0 rows affected (0.00 sec)

mysql> show create table stu_name_index1\G
*************************** 1. row ***************************
       Table: stu_name_index1
Create Table: CREATE TABLE `stu_name_index1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  KEY `name_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建唯一索引
mysql> create table stu_id_index2
    -> (id int primary key auto_increment,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> unique index id_index(id desc));
Query OK, 0 rows affected (0.00 sec)

mysql> show create table stu_id_index2\G
*************************** 1. row ***************************
       Table: stu_id_index2
Create Table: CREATE TABLE `stu_id_index2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_index` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建全文索引
mysql> create table stu_id_index3
    -> (id int,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> fulltext index name_full_index(name));
Query OK, 0 rows affected (0.02 sec)

mysql> show create table stu_id_index3\G
*************************** 1. row ***************************
       Table: stu_id_index3
Create Table: CREATE TABLE `stu_id_index3` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  FULLTEXT KEY `name_full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)



# 创建多列索引
```sql
mysql> create table stu_id_index4
    -> (id int,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> index more_index(id,name,gender));
Query OK, 0 rows affected (0.01 sec)

mysql> show create table stu_id_index4\G
*************************** 1. row ***************************
       Table: stu_id_index4
Create Table: CREATE TABLE `stu_id_index4` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  KEY `more_index` (`id`,`name`,`gender`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建空间索引
mysql> create table stu_id_index5
    -> (id int,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> hobby geometry not null,
    -> spatial index space_index(hobby))
    -> ENGINE=MyISAM DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> show create table stu_id_index5\G
*************************** 1. row ***************************
       Table: stu_id_index5
Create Table: CREATE TABLE `stu_id_index5` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  SPATIAL KEY `space_index` (`hobby`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

注:1、全文索引,只能给char、varchar、text类型的字段创建;
2、创建多列索引时一定要特别注意,只有使用了索引中的第一个字段时才会触发索引。如果没有使用索引中的第一个字段,那么这个多列索引就不会起作用

3、创建空间索引时,表的存储引擎必须是myisam类型,而且索引字段必须有非空约束。空间数据类型包括geometry,point,linestring和polygon类型等;

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

使用"create index""创建

# 创建学生表
mysql> create table student
    -> (id int primary key auto_increment,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> hobby geometry not null);
Query OK, 0 rows affected (0.01 sec)
# 查看学生表结构
mysql> desc student;
+--------+-------------------+------+-----+---------+----------------+
| Field  | Type              | Null | Key | Default | Extra          |
+--------+-------------------+------+-----+---------+----------------+
| id     | int(11)           | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)       | YES  |     | NULL    |                |
| gender | enum('男','女')   | YES  |     ||                |
| hobby  | geometry          | NO   |     | NULL    |                |
+--------+-------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)


# 创建普通索引
mysql> create index ordinary_index 
    -> on student(name);
    Query OK, 0 rows affected (0.00 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  KEY `ordinary_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建唯一索引
mysql> create unique index unique_index
    -> on student(id);
    Query OK, 0 rows affected (0.01 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> create fulltext index full_index
    -> on student(name);
Query OK, 0 rows affected, 1 warning (0.48 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建多列索引
mysql> create index more_index on student(id,name,gender);
Query OK, 0 rows affected (0.00 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  KEY `more_index` (`id`,`name`,`gender`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建空间索引
mysql> create spatial index space_index on student(hobby);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  KEY `more_index` (`id`,`name`,`gender`),
  SPATIAL KEY `space_index` (`hobby`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

使用"alter table""创建

# 创建student表
mysql> create table student
    -> (id int primary key auto_increment,
    -> name varchar(20),
    -> gender enum('男','女') default '男',
    -> hobby geometry not null);
Query OK, 0 rows affected (0.01 sec)

# 查看表结构
mysql> desc student;
+--------+-------------------+------+-----+---------+----------------+
| Field  | Type              | Null | Key | Default | Extra          |
+--------+-------------------+------+-----+---------+----------------+
| id     | int(11)           | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)       | YES  |     | NULL    |                |
| gender | enum('男','女')   | YES  |     ||                |
| hobby  | geometry          | NO   |     | NULL    |                |
+--------+-------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

# 创建普通索引
mysql> alter table student
    -> add index ordinary_index(name);
Query OK, 0 rows affected (0.00 sec)
mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  KEY `ordinary_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建惟一索引
mysql> alter table student
    -> add unique unique_index(id);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建全文索引
mysql> alter table student 
    -> add fulltext index full_index(name);
Query OK, 0 rows affected, 1 warning (6.07 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

# 创建多列索引
mysql> alter table student
    -> add index more_index(id,name,gender);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  KEY `more_index` (`id`,`name`,`gender`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 创建空间索引
mysql> alter table student
    -> add spatial index space_index(hobby);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  KEY `more_index` (`id`,`name`,`gender`),
  SPATIAL KEY `space_index` (`hobby`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

删除索引

# 查看student表的索引
mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`id`),
  KEY `ordinary_index` (`name`),
  KEY `more_index` (`id`,`name`,`gender`),
  SPATIAL KEY `space_index` (`hobby`),
  FULLTEXT KEY `full_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

# 删除student所有索引
mysql> drop index unique_index on student;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index ordinary_index on student;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index more_index on student;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index space_index on student;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index full_index on student;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 查看student表的索引
mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `gender` enum('男','女') DEFAULT '男',
  `hobby` geometry NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

单列索引、普通索引的创建方法相同。

三、索引 案例实战

1、在数据库job下创建work_info表。创建表的同时在id字段上创建名为index_id的唯一性索引,而且以降序的格式排列。
# workInfo表内容如下所示
          字段描述        数据类型        主键   外键   非空  唯一   自增
id        编号            INT(10)         是     否     是   是      是
name      职位名称        VARCHAR(20)     否     否     是   否      否
type      职位类别        VARCHAR(10)     否     否     否   否      否
address   工作地址        VARCHAR(50)     否     否     否   否      否
wage      工资            INT             否     否     否   否      否
contents  工作内容        TINYTEXT        否     否     否   否      否
extra     附加信息        TEXT            否     否     否   否      否

# 创建work_info表
mysql> create table work_info
    -> (id int primary key auto_increment,
    -> name varchar(20) not null,
    -> type varchar(10),
    -> address varchar(50),
    -> tel varchar(20),
    -> wage int,
    -> content tinytext,
    -> extra text,
    -> unique index index_id(id desc));
Query OK, 0 rows affected (0.05 sec)

# 查看表结构
mysql> desc work_info;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| name    | varchar(20) | NO   |     | NULL    |                |
| type    | varchar(10) | YES  |     | NULL    |                |
| address | varchar(50) | YES  |     | NULL    |                |
| tel     | varchar(20) | YES  |     | NULL    |                |
| wage    | int(11)     | YES  |     | NULL    |                |
| content | tinytext    | YES  |     | NULL    |                |
| extra   | text        | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

# 查看建表语句
mysql> show create table work_info\G
*************************** 1. row ***************************
       Table: work_info
Create Table: CREATE TABLE `work_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type` varchar(10) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `wage` int(11) DEFAULT NULL,
  `content` tinytext,
  `extra` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

2、使用create index语句为name字段创建长度为10的索引index_name
mysql> create index index_name on work_info(name(10));
Query OK, 0 rows affected (0.01 sec)

mysql> show create table work_info\G
*************************** 1. row ***************************
       Table: work_info
Create Table: CREATE TABLE `work_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type` varchar(10) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `wage` int(11) DEFAULT NULL,
  `content` tinytext,
  `extra` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_id` (`id`),
  KEY `index_name` (`name`(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

3、使用alter table语句在type和address上创建名为index_t的索引
mysql> alter table work_info
    -> add index index_t(type,address);
Query OK, 0 rows affected (0.00 sec)

mysql> show create table work_info\G
*************************** 1. row ***************************
       Table: work_info
Create Table: CREATE TABLE `work_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type` varchar(10) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `wage` int(11) DEFAULT NULL,
  `content` tinytext,
  `extra` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_id` (`id`),
  KEY `index_name` (`name`(10)),
  KEY `index_t` (`type`,`address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

4、将workInfo表的存储引擎更改为MyISAM类型
mysql> alter table work_info 
    -> engine=myisam;
Query OK, 0 rows affected (0.01 sec)

mysql> show create table work_info\G
*************************** 1. row ***************************
       Table: work_info
Create Table: CREATE TABLE `work_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type` varchar(10) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `wage` int(11) DEFAULT NULL,
  `content` tinytext,
  `extra` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_id` (`id`),
  KEY `index_name` (`name`(10)),
  KEY `index_t` (`type`,`address`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

5、使用alter table语句在extra字段上创建名为index_ext的全文索引
mysql> alter table work_info
    -> add fulltext index index_ext(extra);
Query OK, 0 rows affected (0.00 sec)

mysql> show create table work_info\G
*************************** 1. row ***************************
       Table: work_info
Create Table: CREATE TABLE `work_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type` varchar(10) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `wage` int(11) DEFAULT NULL,
  `content` tinytext,
  `extra` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_id` (`id`),
  KEY `index_name` (`name`(10)),
  KEY `index_t` (`type`,`address`),
  FULLTEXT KEY `index_ext` (`extra`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

6、删除workInfo表的唯一性索引index_id
mysql> drop index index_id on work_info;
Query OK, 0 rows affected (0.01 sec)

mysql> show create table work_info\G
*************************** 1. row ***************************
       Table: work_info
Create Table: CREATE TABLE `work_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `type` varchar(10) DEFAULT NULL,
  `address` varchar(50) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `wage` int(11) DEFAULT NULL,
  `content` tinytext,
  `extra` text,
  PRIMARY KEY (`id`),
  KEY `index_name` (`name`(10)),
  KEY `index_t` (`type`,`address`),
  FULLTEXT KEY `index_ext` (`extra`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

猜你喜欢

转载自blog.csdn.net/XY0918ZWQ/article/details/113615705