欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mysql最左匹配原则与索引选择原则

程序员文章站 2024-03-16 20:54:22
...

一、explain语句分析

1. 作用

	1.1 通常用于sql语句的性能分析
	1.2 打印出一条sql语句优化器的执行计划
	1.3 索引使用情况
	1.4 性能好不好

2. 语法

	 explain + 要操作的sql语句;
explain select * from article where status = 0;

3. 详细字段说明

explain分析sql语句:

mysql最左匹配原则与索引选择原则

id – select识别符。

	这是select的查询***,id的值越大优先级别越高,越先被执行,如果id相同,执行顺序由上至下

select_type – 表示select语句的类型。

	类型:
		SIMPLE:表示最简单的查询,不包括连接查询与子查询
		  explain select * from user where id = (select id from where name="asi");
		PRIMARY:最外层的查询 -- select * from user where id =();
		SUBQUERY:子查询 -- select id from where name="asi"
		  explain select id from where name="asi" union all select id from where name="ayu";
		UNION:合并 联合查询,union 后面的那张表就会表示成它
		UNION RESULT:联合结果
		DERIVED: 衍生查询-在select出一批自定义列的数据,概念上相当于一张表,但是该表只在语句执行过程出现和

table – 与查询语句相关的表。

partitions – 表分区,参数的使用

type – 表示的是表的连接类型。

	类型:
		①all:遍历全表数据查询

		②index:只遍历索引树上的数据查询

		③range:只检索给定范围的行,使用一个索引来选择行,条件过滤,索引定位

		④ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

		⑤null :MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

		⑥eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,
			      简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

		⑦const:当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量。

		⑧system: system是const类型的特例,当查询的表只有一行的情况下,使用system

	效率排行榜:
	8 > 7 > 6 > 4 > 5 > 3 > 2 > 1

possible_keys – 可能使用的索引

key – 使用的索引

key_len表示mysql使用的索引字段按字节计算的长度,如果键是null,则长度为null

	注意通过key_len值可以确定mysql将实际使用一个多列索引中的几个字段

ref – 表示使用哪个列或常数与索引一起来查询记录

		①all 全表查询没有使用索引
		
		②count 主键索引查询

rows – 显示mysql表中进行查询时扫描的数据量,并不是很精确(约等于)

filtered

Extra – 显示mysql在处理查询时的详细信息(额外的信息)。

	类型:
		① Using filesort: 如果根据索引列进行排序(order by 索引列)是可以用到索引的,SQL查询引擎会先根据索引列进行排序,
				    然后获取对应记录的主键id执行回表操作,如果排序字段用不到索引则只能在内存中或磁盘中进行排序操作,
			            MySQL把这种在内存或者磁盘上进行排序的方式统称为文件排序(英文名:filesort),
				    如果某个查询需要使用文件排序的方式执行查询,就会在执行计划的Extra列中显示Using filesort

		② Using temporary: 许多查询的执行过程中,MySQL会借助临时表来完成一些功能,
					比如去重、排序、合并、分组之类的,比如我们在执行许多包含distinct、group by、union等子句的查询过程中,
					如果不能有效利用索引来完成查询,MySQL很有可能寻求通过建立内部的临时表来执行查询。
					如果查询中使用到了内部的临时表,在执行计划的Extra列将会显示Using temporary提示.

		③ USING index: 表示相应的select操作中使用了覆盖索引(Covering Index),避免回表操作,效率不错!
				如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表名索引用来读取数据而非执行查找动作。

		④ Using where: 使用了where过滤

		⑤ using join buffer: 在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,
					MySQL一般会为其分配一块名叫join buffer的内存块来加快查询速度

		⑥ impossible where: where子句的值总是false,不能用来获取任何元组

		⑦ select tables optimized away: 在没有GROUPBY子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,
					  	     不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。

		⑧ distinct: 优化distinct,在找到第一匹配的元组后即停止找同样值的工作

		⑨ Using index condition:查找使用了索引,但是需要回表查询数据

二、联合索引结构与最左匹配原则

1. 联合索引结构

mysql最左匹配原则与索引选择原则

1.1 简介

多个字段组合起来的索引(两个以上) idx_name_age(name,age)

2. 最左匹配原则

2.1 简介

最左前缀匹配原则:在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。

2.2 建立联合索引

alter table 'user' add index idx_name_age_sex(name,age,sex);
	建立了这个联合索引相当于生成了3个索引
		idx_name_age_sex =》(name)、(name,age) 、(name,age,sex)

3. 验证

3.1 验证最左匹配原则是否与条件顺序有关?

		验证语句:
			explain select * from user where name='asi' and age=21 and sex=1; 
			explain select * from user where name='asi' and sex=1 and age=21 ; 
			explain select * from user where sex=1 and name='asi' and age=21 ; 
			explain select * from user where age=21 and name='asi' and sex=1; 
		结果:
			都可以使用到联合索引
		结论:
			只要条件当中有索引列,那么sql语句就可以命中索引,最左匹配原则与条件的先后顺序无关。

3.2 验证最左匹配原则匹配最左边的列?

		验证语句:
			explain select * from user where name='asi'; 
			explain select * from user where name='asi' and age=21; 
			explain select * from user where name='asi' and sex=1; 
			explain select * from user where age=21 and sex=1; 
		结果:
			前面两个可以使用联合索引并且是覆盖索引
			第三个使用了条件过滤
			最后一个回表了
		结论:	
			只要是按照了索引创建顺序来编写where条件,就可以使用到这个联合索引,并且大几率是覆盖索引

3.3 最左原则总结

最左匹配原则与条件中的字段顺序无关,只需要按照索引的创建顺序,最左字段存在即可。

三、mysql对于索引优先考虑对象

1. 简介

使用场景:

	要创建索引的时候要考虑到的因素(分组、排序)

sql语句:

select * from user where sex =1 and name='asi' group by id order by id;

MySQL优化器在选择索引时的策略

	mysql对于索引使用的优先级:
		where > group by > order by
		
		1. 优先过滤条件where上的字段
		2. 分组 =》排序
		3. 返回的结果默认不会作为考虑的对象,最后考虑只有覆盖索引的时候才会考虑

2. 条件与分组、排序共存的情况下

mysql最左匹配原则与索引选择原则

2.1 原因

当sql中where条件,分组,排序同时存在时,MySQL的优化器会优先选择条件来确定使用的索引,因为where可以减少更多的sql扫描,而排序和分组往往进行的是全表扫描。

3. 条件与排序共存

mysql最左匹配原则与索引选择原则

3.1 原因

所有的排序都是在条件过滤之后才执行的,所以如果条件过滤了大部分数据的话,几百几千条数据进行排序其实并不是很消耗性能,即使索引优化了排序但实际提升性能很有限。

4. 分组排序共存

4.1 原因

对于分组和排序共存的情况下,mysql会优先根据分组去选择索引,那是因为sql需要先将要查询的数据进行分组,随后才会进行数据的排序

5. 优化方案

将条件字段以及分组字段和排序字段,都建立在索引中

四、mysql索引的挑选原则

1.索引字段的选择

字段一般是推荐重复比较少的字段影响到数据的检索,如果是项目需求(可建立联合索引)

2. 挑选原则

1. 唯一字段可以单独建立单索引,非唯一考虑联合索引,推荐尽量使用唯一字段建立索引

2. 索引的个数,联合索引的个数 最佳 6个 以内,如果索引因为项目需求:最多 10个

3. 索引的使用遵循最左匹配原则其次覆盖索引

4. 尽量选择小的字段建立索引 int ,varchar(10), char(5)

5. 避免<,<= ,> ,>= ,like(%),between 之间的条件(in不算在其中)。选择索引的字段的范围和模糊之前,
因为范围与模糊会引起索引失效,针对于联合索引,就是联合索引的中间尽量不要有范围查询的字段
	like中的前缀匹配还好,别的就不行了

6. 尽量多使用explain分析

7. 避免更新频繁的字段 (二叉树会一直变化,导致性能变慢)

8. 建立的索引- 优先考虑 建立 联合索引

9. 索引字段不要有 null, 不是 ''
                              六星教育--2008期mysql优化--李建宇