索引及执行计划
1. 介绍
相当于一本书中的目录,可以加速查询(select ,update,delete ).
2.种类
Btree (平衡多叉树): b-tree b+tree(b*tree),优点:范围查找
HASH : 优点,比较适合随机的等值.
Rtree
2. MySQL 支持的索引类型(算法)
Btree : 平衡多叉树
Rtree :空间树所以
Hash :HASH索引
Fulltext :全文索引
3.btree的细分
聚簇索引 : 主键索引
辅助索引 :
单列
联合
唯一
前缀
#MySQL Btree索引的应用
聚簇索引(聚集索引、主键索引)
前提:
0. InnoDB存储引擎的表才会有聚簇索引。
1. 有主键,主键就是聚簇索引
2. 没有主键,选择唯一键作为聚簇索引
3. 没有主键和唯一键生成一个隐藏列(DB_ROW_ID,6字节),作为聚簇索引
作用:
1. 聚簇(区)索引,组织表(IOT): 所有数据在插入时,都按照ID(主键)属性,在相邻数据页上有序存储数据。
2. 加快存储数据,加快通过索引作为查找条件的查询。
#参考网址 https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html
4.索引的构建过程
聚簇索引构建过程
1. 叶子节点 :
由于存储数据时,已经按照ID顺序在各个数据页中有序存储了,所以《原表数据》所在数据页被作为叶子节点。
2. 内部节点(非叶子节点):
获取叶子节点ID范围+指针。
3. 根节点:
获取非叶子节点 ID范围+指针
辅助索引构建过程:
1. 叶子节点构建:
提取索引列值+ID ,进行从小到大排序(辅助索引列值),存储到各个数据页,作为Leaf node。
2. 非叶子节点(internel node )
提取下层的辅助索引列值范围+指针。
3. 根节点:
提取下层节点的范围+指针。
对于查询的优化:
1. 通过辅助索引列,进行条件查询,根据辅助索引BTREE快速锁定条件值对应的ID。
2. 通过得出的ID值,回到聚簇索引继续查询到具体的数据行(回表)。
5.辅助索引的分类
普通单列
联合索引
idx(a,b)
叶子节点:
id+a+b ,按照a和b进行排序,生成叶子节点
枝节点和根节点:
只会包含最左列(a列)的范围+指针
注意: 最左原则
1. 建索引,最左列重复值少的。
2. 查询条件中,必须包含最左列。
唯一索引
unique key
前缀索引
idex(test(10))
6.回表是什么
辅助索引扫描之后,得到ID,再回到聚簇索引查找的过程.
6.1 会表带来什么问题
IO : 次数和量会增加.
IOPS : 1000次/s
吞吐量 : 300M/s
6.2 咋样减少回表
a. 建索引使用联合索引(覆盖),尽可能多将查询条件的数据包含联合索引中.
b. 精细查询条件(业务方面,> and < ,limit)
c. 查询条件要符合联合索引规则,覆盖的列越多越好.
7.索引的管理
7.1压测
mysql> source /root/t100w.sql
mysql> grant all on *.* to root@'10.0.0.%' identified by '123';
## /root/t100w.sql 这个表放在博客园文件当中
[root@oldboy ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='test' --query="select * from test.t100w where k2='780P'" engine=innodb --number-of-queries=2000 -uroot -p123 -h10.0.0.50 -verbose
--concurrency=100 : 模拟同时100会话连接
--create-schema='test' : 操作的库是谁
--query="select * from test.t100w where k2='780P'" :做了什么操作
--number-of-queries=2000 : 一共做了多少次查询
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
Running for engine rbose
Average number of seconds to run all queries: 741.086 seconds
Minimum number of seconds to run all queries: 741.086 seconds
Maximum number of seconds to run all queries: 741.086 seconds
Number of clients running queries: 100
Average number of queries per client: 20
7.2查询表的索引
desc t100w;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | YES | | NULL | |
| num | int(11) | YES | | NULL | |
| k1 | char(2) | YES | | NULL | |
| k2 | char(4) | YES | | NULL | |
| dt | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
5 rows in set (0.00 sec)
-----
Key
-----
PK --> 主键(聚簇索引)
MUL --> 辅助索引
UK --> 唯一索引
mysql> show index from t100w;
8.创建索引
8.1单列辅助索引
mysql> select * from test.t100w where k2='780P';
优化方式:
语法:
alter table 表名 add index 索引名(列名);
alter table t100w add index idx_k2(k2);
8.2联合索引创建
mysql> alter table t100w add index idx_k1_num(k1,num);
Query OK, 0 rows affected (3.39 sec)
Records: 0 Duplicates: 0 Warnings: 0
8.3 前缀索引创建
判断前缀长度多少合适:
select count(distinct(left(name,5))) from city ;
select count(distinct name) from city ;
创建前缀索引
mysql> alter table city add index idx_n(name(5));
8.4 删除索引
mysql> alter table city drop index idx_n;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0