第四章 索引及执行计划
Posted 熊孩子Ajie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四章 索引及执行计划相关的知识,希望对你有一定的参考价值。
1、索引的作用
类似于一本书中的目录,起到优化查询的作用
2、索引的分类(算法)
B树 默认使用的索引类型
R树
Hash
FullText 全文索引 类似 “ES”
GIS 索引 地理位置索引 类似“MongoDB”
3、BTREE索引算法演变(了解)
4、Btree索引功能上的分类
4.1 辅助索引构建过程
(1) 索引是基于表中,列(索引键)的值生成的B树结构
(2) 首先提取此列所有的值,进行自动排序
(3) 将排好序的值,均匀的分布到索引树的叶子节点中(16K)
(4) 然后生成此索引键值所对应得后端数据页的指针
(5) 生成枝节点和根节点,根据数据量级和索引键长度,生成合适的索引树高度
4.2 聚集索引构建前提及过程
构建前提
(1)表中设置了主键,主键列就会自动被作为聚集索引
(2)如果没有主键,会选择唯一键作为聚集索引
(3)聚集索引必须在建表时才有意义,一般是表的无关列(ID)
构建过程
(1) 在建表时,设置了主键列(ID)
(2) 在将来录入数据时,就会按照ID列的顺序存储到磁盘上.(我们又称之为聚集索引组织表)
(3) 将排好序的整行数据,生成叶子节点.可以理解为,磁盘的数据页就是叶子节点
4.3 聚集索引和辅助索引的区别
(1) 聚集索引只能有一个,非空唯一,一般是主键
(2) 辅助索引,可以有多个,是配合聚集索引使用的
(3) 聚集索引叶子节点,就是磁盘的数据行存储的数据页.
(4) MySQL是根据聚集索引,组织存储数据,数据存储时就是按照聚集索引的顺序进行存储数据
(5) 辅助索引,只会提取索引键值,进行自动排序生成B树结构
5、辅助索引细分
1)单列辅助索引
2)联合索引(覆盖索引) *****
3)多个列作为索引条件,生成索引树,理论上设计是好的,可以减少大量的回表查询
唯一索引 索引列的值都是唯一的
6、索引树高度
索引树高度应当越低越好,一般维持在3-4最佳
1)数据量级,解决方法:分片,分库分表,分布式架构
2)索引列值过长,解决方法:前缀索引
3)数据类型,变长长度字符串使用char,可变长长度字符串使用varchar
7、索引的命令操作
7.1 查询索引
desc city;
PRI ==> 主键索引
MUL ==> 辅助索引
UNI ==> 唯一索引
mysql> show index from city\\G
7.2 创建索引
单列的辅助索引
mysql> alter table city add index idx_name(name);
多列的联合索引
mysql> alter table city add index idx_c_p(countrycode,population);
唯一索引:
mysql> alter table city add unique index uidx_dis(district);
mysql> select count(district) from city;
mysql> select count(distinct district) from city;
前缀索引
mysql> alter table city add index idx_dis(district(5));
7.3 删除索引
mysql> alter table city drop index idx_name;
mysql> alter table city drop index idx_c_p;
mysql> alter table city drop index idx_dis;
8、压力测试准备
mysql> create database test charset utf8mb4;
mysql> use test
mysql> source /tmp/t100w.sql
8.1 未做优化之前测试(100个用户连接查询2000次)
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf \\
--concurrency=100 --iterations=1 --create-schema=\'test\'
--query="select * from test.t100w where k2=\'MN89\'" engine=innodb
--number-of-queries=2000 -uroot -p123 -verbose
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: 755.861 seconds
Minimum number of seconds to run all queries: 755.861 seconds
Maximum number of seconds to run all queries: 755.861 seconds
Number of clients running queries: 100
Average number of queries per client: 20
8.2 索引优化后
mysql> alter table t100w add index idx_k2(k2);
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema=\'test\' --query="select * from test.t100w where k2=\'MN89\'" engine=innodb --number-of-queries=2000 -uroot -p123 -verbose
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: 1.678 seconds
Minimum number of seconds to run all queries: 1.678 seconds
Maximum number of seconds to run all queries: 1.678 seconds
Number of clients running queries: 100
Average number of queries per client: 20
9、执行计划分析
9.1 作用
获取到的是优化器选择完成的,他认为代价最小的执行计划
作用: 语句执行前,先看执行计划信息,可以有效的防止性能较差的语句带来的性能问题
如果业务中出现了慢语句,我们也需要借助此命令进行语句的评估,分析优化方案
9.2 获取执行
desc SQL 语句
explain SQL 语句
9.3 分析执行计划
9.3.1 table
表名
9.3.2 type
查询的类型:
全表扫描: ALL
索引扫描: index,range,ref,eq_ref,const(system),NULL
index: 全索引扫描
查询需要获取整个索引树中的值时
mysql> desc select countrycode from city;
range: 索引范围扫描(> < >= <= , between and ,or,in,like )
mysql> desc select * from city where id>2000;
mysql> desc select * from city where countrycode like \'CH%\';
注意事项:
对于辅助索引来讲,!= 和not in等语句是不走索引的
对于主键索引列来讲,!= 和not in等语句是走range
mysql> desc select * from city where countrycode=\'CHN\' or countrycode=\'USA\';
mysql> desc select * from city where countrycode in (\'CHN\',\'USA\');
一般改写为 union all
desc
select * from city where countrycode=\'CHN\'
union all
select * from city where countrycode=\'USA\';
ref: 辅助索引等值查询
desc
select * from city where countrycode=\'CHN\'
union all
select * from city where countrycode=\'USA\';
eq_ref : 多表连接时,子表(除驱动表外,驱动表的索引都是ALL)使用主键列或唯一列作为连接条件
A join B
on a.x = B.y
desc select b.name,a.name ,a.population
from city as a
join country as b
on a.countrycode=b.code
where a.population<100;
const(system) : 主键或者唯一键的等值查询
mysql> desc select * from city where id=100;
possible_key
key
key_len
Extra
以上是关于第四章 索引及执行计划的主要内容,如果未能解决你的问题,请参考以下文章