在进行索引操作之前,可以进行一个压力测试,将一个100W数据量的数据库备份数据进行备份恢复:
# 进行测试数据恢复操作:
mysql> source ~/t100w.sql
# 导入数据后进行验证
mysql> show tables from zq;
+--------------+
| Tables_in_zq |
+--------------+
| t100w |
+--------------+
1 row in set (0.00 sec)
# 查看表的总行数为1000000
mysql> select count(*) from zq.t100w;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.01 sec)
# 进行数据库程序服务压测,观察到用时的最大值、最小值、平均值为85.745秒
[root@master ~]# mysqlslap --defaults-file=/data/3306/data/my.cnf --concurrency=100 --iterations=1 --create-schema='zq' --query="select * from zq.t100w where k2='VWlm'" engine=innodb --number-of-queries=2000 -verbose
Benchmark
Running for engine rbose
Average number of seconds to run all queries: 85.745 seconds
Minimum number of seconds to run all queries: 85.745 seconds
Maximum number of seconds to run all queries: 85.745 seconds
Number of clients running queries: 100
Average number of queries per client: 20
# 补充说明:如果涉及mysql用户和密码,可以参考下面格式
mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='zq' --query="select * from zq.t100w where k2='VWlm'" engine=innodb --number-of-queries=2000 -uroot -p123456 -h10.0.0.51 -verbose
相关参数说明:
- concurrency=100 模拟同时100会话连接,这个需要注意数据库max_connections的参数值(默认151),可以通过
select @@max_connections;这个sql语句进行查询; - iterations=1 测试执行的迭代次数,代表要在不同并发环境下,各自运行测试多少次
- create-schema='test' 指定操作的数据库信息;
- query="select * from test.100w where k2='780P'" 指定压测过程具体执行了什么语句操作
- number-of-queries=2000 指定一共做了多少次查询,总的测试查询次数(并发客户数×每客户查询次数)
数据库压力测试结果情况:

进行索引建立优化:
mysql> alter table zq.t100w add index idx_k2(k2);
重新进行压力测试,观察到时间已将为0.883秒
[root@master ~]# mysqlslap --defaults-file=/data/3306/data/my.cnf --concurrency=100 --iterations=1 --create-schema='zq' --query="select * from zq.t100w where k2='VWlm'" engine=innodb --number-of-queries=2000 -verbose
Benchmark
Running for engine rbose
Average number of seconds to run all queries: 0.883 seconds
Minimum number of seconds to run all queries: 0.883 seconds
Maximum number of seconds to run all queries: 0.883 seconds
Number of clients running queries: 100
Average number of queries per client: 20
在进行压测检查确认:

一、索引基本操作说明¶
环境准备:
-- 将world.sql数据库文件上传到数据库服务器中,根据存储路径进行加载恢复数据库数据
[root@master ~]# unzip world.zip
-- 导入sql语句方式一:进入数据库中执行source语句
mysql> source /root/world.sql
-- 导入sql语句方式二:数据库外使用<符号进行导入
[root@master ~]# mysql < /root/world.sql
-- 查看表
mysql> use world;
mysql> show tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city |
| country |
| countrylanguage |
+-----------------+
3 rows in set (0.00 sec)
二、查询索引信息¶
-- 查询表结构信息,获取索引配置
mysql> use world;
mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+----------------+
| ID | int | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| CountryCode | char(3) | NO | MUL | | |
| District | char(20) | NO | | | |
| Population | int | NO | | 0 | |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

索引信息的展示形式:
| 序号 | 索引标识 | 解释说明 |
|---|---|---|
| 01 | PK(PRI) | 表示为聚簇索引,也可以理解为主键索引 |
| 02 | K(MUL) | 表示为辅助索引,也可以理解为一般索引 |
| 03 | UK | 表示唯一键索引 |
-- 查询表索引信息,获取索引详细信息
mysql> use world;
mysql> show index from city\G
*************************** 1. row ***************************
Table: city
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: ID
Collation: A
Cardinality: 4188
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: city
Non_unique: 1
Key_name: CountryCode
Seq_in_index: 1
Column_name: CountryCode
Collation: A
Cardinality: 232
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
2 rows in set (0.00 sec)
-- 算下city表行数
mysql> select count(*) from city;
+----------+
| count(*) |
+----------+
| 4079 |
+----------+
1 row in set (0.00 sec)

回显重要参数解读:
- Non_unique:索引信息是否是唯一键值索引,其中0表示唯一,1 表示可以重复
- Collation:显示创建索引排序方式,其中A代表升序,D代表降序
- Cardinality:显示索引列的索引选择度,数据库会自动计算估值,索引列数据重复情况。先通过
select count(*) from city;计算city表总行数4079,这里4188/4079约等于1,表示重复值越少;这里232/4079约等于0,表示重复值越多。 - Sub_part:当设置前缀索引时,会显示截取的前缀字符数量
- Visible:是否临时禁用索引功能,可以影响日常批量操作效率
三、创建索引信息¶
环境准备
-- 创建数据库db18
mysql> create database db18;
3.1 创建单列索引¶
创建单列索引语法格式
-- 创建主键索引,主键索引是一种特殊的唯一索引,一个表中只能有一个主键索引,不允许有空值
mysql> CREATE TABLE `table_name` ( ...,PRIMARY KEY ( `column` ))
mysql> ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
-- 创建辅助索引,辅助索引又称为普通索引,是MySOL中的基本索引类型,允许在定义索引的列中插入重复值和空值
mysql> CREATE TABLE `table_name` ( ...,index index_name(column(length))
mysql> CREATE index `index_name` on table(column(length))
mysql> alter table `table_name` add index `index_name` (column(length));
mysql> alter table `table_name` add index `index_name` on (column(length));
-- 创建唯一键索引,唯一索引指索引列的值必须唯一,但允许有空值;如果是组合素引,则列值的组合必须唯一;
mysql> CREATE TABLE `table_name` ( ...,unique index index_name(column(length))
mysql> CREATE unique index `index_name` on table(column(length))
mysql> ALTER TABLE `table_name` ADD UNIQUE `index_name` on (column(length));

3.1.1 创建主键索引¶
情况一:创建表的时候将索引创建
-- 创建表的时候顺带创建主键索引
mysql> create table db18.test01(id int,name char(10),primary key(id));
-- 结果验证
mysql> desc db18.test01;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
情况二:创建表之后再创建索引
-- 先创建表test02
mysql> create table db18.test02(id int,name char(10));
-- 在已有表的基础创建主键索引
mysql> alter table db18.test02 ADD primary key(id);
-- 结果验证,查看索引
mysql> desc db18.test02;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> show index from db18.test02\G;
*************************** 1. row ***************************
Table: test02
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
ERROR:
No query specified
3.1.2 创建辅助索引¶
情况一:创建表的时候将索引创建
-- 创建表的时候顺带创建辅助索引,不带前缀
mysql> create table db18.test03(id int,name char(10),index index_name(name));
-- 结果验证
mysql> desc db18.test03;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(10) | YES | MUL | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
-- 创建表的时候顺带创建辅助索引,设置排序方式为降序
mysql> create table db18.test05(id int,name char(10),age char(5),index zq(name desc));
-- 结果验证,观察Collation的值为D,代表为降序
mysql> show index from db18.test05\G;
*************************** 1. row ***************************
Table: test05
Non_unique: 1
Key_name: zq
Seq_in_index: 1
Column_name: name
Collation: D
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
情况二:创建表之后再创建索引
-- 先创建表test08
mysql> create table db18.test08(id int,name char(10));
-- 在已有表的基础添加辅助索引
mysql> alter table db18.test08 ADD index index_name(name);
-- 结果验证,查看索引
mysql> desc db18.test08;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(10) | YES | MUL | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
3.1.3 创建唯一键索引¶
情况一:创建表的时候将索引创建
-- 创建表的时候顺带创建唯一索引
mysql> create table db18.test06(id int,name char(10),unique index index_name(name));
-- 结果验证,观察到Key字段为UNI
mysql> desc db18.test06;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(10) | YES | UNI | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
情况二:创建表之后再创建索引
-- 先创建表test09
mysql> create table db18.test09(id int,name char(10));
-- 在已有表的基础添加唯一索引
mysql> alter table db18.test09 ADD unique index index_name(name);
-- 结果验证,查看索引
mysql> desc db18.test09;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(10) | YES | UNI | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
3.2 创建联合索引(多列索引)¶
作用:减少查询数据信息时回表次数
情况一:创建表的时候将索引创建
-- 创建表的时候顺带创建联合索引
mysql> create table db18.test07(id int,name char(10),age char(5),index index_name(name,age));
-- 结果验证,观察到Seq_in_index字段为1和2
mysql> SHOW INDEX FROM db18.test07\G;
*************************** 1. row ***************************
Table: test07
Non_unique: 1
Key_name: index_name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: test07
Non_unique: 1
Key_name: index_name
Seq_in_index: 2
Column_name: age
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
2 rows in set (0.00 sec)
情况二:创建表之后再创建索引
-- 先创建表test10
mysql> create table db18.test10(id int,name char(10),age char(5));
-- 在已有表的基础添加唯一索引
mysql> alter table db18.test10 ADD index index_name(name,age);
-- 结果验证,查看索引
-- 结果验证,观察到Seq_in_index字段为1和2
mysql> SHOW INDEX FROM db18.test10\G;
*************************** 1. row ***************************
Table: test10
Non_unique: 1
Key_name: index_name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: test10
Non_unique: 1
Key_name: index_name
Seq_in_index: 2
Column_name: age
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
2 rows in set (0.00 sec)
3.3 创建前缀索引¶
mysql> alter table city add index ix_n(name(10));

情况一:创建表的时候将索引创建
-- 创建表的时候顺带创建辅助索引,带前缀
mysql> create table db18.test04(id int,name char(10),index index_name(name(5)));
-- 结果验证,观察到Sub_part这个字段显示值为5
mysql> show index from db18.test04\G;
*************************** 1. row ***************************
Table: test04
Non_unique: 1
Key_name: index_name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 0
Sub_part: 5
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
情况二:创建表之后再创建索引
-- 先创建表test11
mysql> create table db18.test11(id int,name char(10));
-- 在已有表的基础添加辅助索引
mysql> alter table db18.test11 ADD index index_name(name(5));
-- 结果验证,观察到Sub_part这个字段显示值为5
mysql> show index from db18.test11\G;
*************************** 1. row ***************************
Table: test11
Non_unique: 1
Key_name: index_name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 0
Sub_part: 5
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
四、删除索引信息¶
# 删除索引信息(一般索引)
alter table 表名 drop index 索引名;
mysql> alter table t100w drop index idx_name;
-- 删除辅助索引
mysql> alter table t100w drop index oldboy;
-- 删除联合索引
mysql> alter table t100w drop index id;
-- 删除唯一索引
# 删除索引信息(聚簇索引)
alter table 表名 drop primary key;
mysql> alter table t100w drop primary key;
-- 删除聚簇索引

4.1 删除聚簇索引¶
环境准备
-- 创建表的时候顺带创建主键索引
mysql> create table db18.test01(id int,name char(10),primary key(id));
-- 结果验证
mysql> desc db18.test01;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
删除聚簇索引
mysql> alter table db18.test01 drop primary key;
结果验证
mysql> desc db18.test01;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | NO | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
4.2 删除辅助索引¶
环境准备
-- 创建表的时候顺带创建辅助索引,不带前缀
mysql> create table db18.test03(id int,name char(10),index index_name(name));
-- 结果验证
mysql> desc db18.test03;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(10) | YES | MUL | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
-- 创建表的时候顺带创建辅助索引,设置排序方式为降序
mysql> create table db18.test05(id int,name char(10),age char(5),index zq(name desc));
-- 结果验证,观察Collation的值为D,代表为降序
mysql> show index from db18.test05\G;
*************************** 1. row ***************************
Table: test05
Non_unique: 1
Key_name: zq
Seq_in_index: 1
Column_name: name
Collation: D
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
删除辅助索引
mysql> alter table db18.test03 drop index index_name;
结果验证
-- 结果验证
mysql> desc db18.test03;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)