Mysql索引及执行计划(之索引)部分

索引及执行计划

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

posted @ 2021-05-14 16:38  断尽的记忆  阅读(108)  评论(0编辑  收藏  举报