59. MySQL索引是如何提高查询效率的呢?(MySQL面试第二弹)下
选择合适的索引类型
从数据结构角度来看,MySQL支持的索引类型有B树索引、Hash索引等。
B树索引
B树索引对于<、<=、 =、 >=、 >、 <>、!=、 between查询,进行精确比较操作和范围比较操作都有比较高的效率。
B树索引也是InnoDB存储引擎默认的索引结构。
Hash索引
Hash索引仅能满足=、<=>、in查询。
Hash索引检索效率非常高,索引的检索可以一次定位,不像B树索引需要从根节点到枝节点,最后才能访问到页节点这样多次的I/O访问,所以Hash索引的查询效率要远高于B树索引。但Hash索引不能使用范围查询。
查询优化建议
下面提供几个查询优化的建议。
使用explain分析查询语句
前面已经演示过如何使用explain命令分析查询语句了,这里再解释一下其中几个有参考价值的字段的含义:
select_type
select_type表示查询中每个select子句的类型,一般有下面几个值:
SIMPLE
简单SELECT,不使用UNION或子查询等。
PRIMARY
查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY。
UNION
UNION中的第二个或后面的SELECT语句。
DEPENDENT UNION
UNION中的第二个或后面的SELECT语句,取决于外面的查询。
UNION RESULT
UNION的结果。
SUBQUERY
子查询中的第一个SELECT。
DEPENDENT SUBQUERY
子查询中的第一个SELECT,取决于外面的查询。
DERIVED
派生表的SELECT, FROM子句的子查询。
UNCACHEABLE SUBQUERY
一个子查询的结果不能被缓存,必须重新评估外链接的第一行。
type
type表示MySQL在表中找到所需行的方式,又称“访问类型”,常用的类型有:
ALL, index, range, ref, eq_ref, const, system, NULL。
从左到右,性能从差到好。
ALL:
Full Table Scan,MySQL将遍历全表以找到匹配的行。
index:
Full Index Scan,index与ALL区别为index类型只遍历索引树。
range:
只检索给定范围的行,使用一个索引来选择行。
ref:
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。
eq_ref:
类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。
const:
当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。
如将主键置于where列表中,MySQL就能将该查询转换为一个常量。
NULL:
MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
Key
key列显示MySQL实际决定使用的键(索引),如果没有选择索引,键是NULL。
possible_keys
possible_keys指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上如果存在索引则该索引将被列出,但不一定被查询使用。
ref
ref表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。
rows
rows表示MySQL根据表统计信息,以及索引选用的情况,找到所需记录需要读取的行数。这个行数是估算的值,实际行数可能不同。
用好**explain命令是查询优化的第一步 !**
声明NOT NULL
当数据列被声明为NOT NULL以后,在查询的时候就不需要判断是否为NULL,由于减少了判断,可以降低复杂性,提高查询速度。
如果要表示数据列为空,可以使用0等代替。
考虑使用数值类型代替字符串
MySQL对数值类型的处理速度要远远快于字符串,而且数值类型往往更加节省空间。
例如对于“Male”和“Female”可以用“0”和“1”进行代替。
考虑使用ENUM类型
如果你的数据列的取值是确定有限的,可以使用ENUM类型代替字符串。因为MySQL会把这些值表示为一系列对应的数字,这样处理的速度会提高很多。
CREATE TABLE shirts ( name VARCHAR(40), size ENUM('x-small', 'small', 'medium', 'large', 'x-large') ); INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'), ('polo shirt','small'); SELECT name, size FROM shirts WHERE size = 'medium';
总结
索引是一个单独的,存储在磁盘上的数据结构,索引对数据表中一列或者多列值进行排序,索引包含着对数据表中所有数据的引用指针。
本教程从MySQL开始讲起,又介绍了MySQL中索引的使用,最后提供了使用索引的几条原则和优化查询的几个方法。
代替字符串。因为MySQL会把这些值表示为一系列对应的数字,这样处理的速度会提高很多。