面试宝典
redis
https://zhuanlan.zhihu.com/p/528146852
MySql
explain命令详解
id列: 这一列总是包含一个编号,标识select所属的行,如果在语句中没有子查询或者联合查询,那么只会有唯一的select,于是每一行的这一列都将显示一个1。否则,内层的select语句一般会顺序编号,对应其在原始语句中的位置。union的结果总是放在一个匿名临时表中,临时表并不在原SQL中出现,因此它的id列是null。
select_type列: 显示了对应行是简单还是复杂select SIMPLE表示查询不包含子查询和union,如果查询中有任何复杂的子部分,则最外层部分标记为PRIMARY; SUBQUERY表示包含在select列表中的子查询中的select(换句话说不在from子句中); DERIVED表示包含在from子句的子查询中的from,MySQL会递归执行并将结果放到一个临时表中。服务器内部称其为派生表,因为该临时表是从子查询中派生来的; UNION表示在union中的第二个和随后的select被标记为union; UNION RESULT表示用来从UNION的匿名临时表检索结果的select。 除了这些值,SUBQUERY和UNION还可以被标记为DEPENDENT和UNCACHEABLE。DEPENDENT意味着select依赖于外层查询中发现的数据。UNCACHEABLE意味只select中的某些特性阻止结果被缓存于Item_cache中。
table列: 显示对应行正在访问哪个表,通常是表名或者该表的别名(如果SQL定义了别名)。
partitions: 指分区信息。数据库优化有分库、分表、分区;这里的分区值表的分区信息。
type列: 表示sql查询的关联类型或访问类型,即MySql决定如何查找表中的行,查找数据行记录的大概范围。 查询效率从最优到最差:system > const > eq_ref > ref > range > index > ALL system、const:mysql能对查询的某个部分进行优化并将其转化为一个常量(可以看show warnings的结果)。指使用primary key或unique key的索引列进行常数等值查询时,所以表最多有一个匹配行,读取1次,类似常量查询,速度比较快。system是const的特例,表中只有可能一条元祖匹配时为system。(就算film中只有一条记录时,select * from film where id = 1 为const,select * from film 为ALL) eq_ref:两张表进行关联查询时,使用某个表的primary key或unique key索引列进行连接使用,因为主键和唯一索引最多只会返回一条符合条件的记录。这可能是const之外最好的联接类型了,简单的select查询不会出现这种type。 ref:相比eq_ref,(查询条件走索引但不是唯一)不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值比较,可能会找到多个符合条件的行。 range:范围扫描通常出现在in()、between、>、<、>=、<=等操作中。使用一个索引来检索给定范围的行。 index: 同样为全表扫描数据,一般是扫描某个二级索引(非主键索引/非聚簇索引),且能使用索引覆盖拿到结果。这种扫描不是从索引树的根节点开始查找,而是从二级索引的叶子节点遍历和扫描。虽然也是用索引,但该查询效率不高(索引的全扫描而不是从根节点匹配查找),出现这种情况需要优化。 ALL: 即全表扫描,扫描聚簇索引(主键索引)的所有叶子节点。出现这种情况需要增加索引来进行优化。
possible_keys列: 查询语句可能使用哪些索引来查找。可能存在possible_key出现索引列,但是实际key为NULL的情况,这是因为表中数据量不多,mysql认为索引对查询帮助不大,选择了全表扫描。
key列: 显示mysql实际采用哪个索引列对查询进行优化。如果没有使用索引则为NULL,如果想强制mysql使用或者忽略某些索引,在查询中可以使用force index、ignore index。
SELECT * FROM user u force index(idx_user_id_update_time) where u.id=100 order by u.update_time
key_len列: 表示sql查询语句中索引使用到的字节数,这个字节数并不是实际的长度,而是通过计算查询中使用到的索引中的长度得出来的,显示的是索引字段最大的可能长度。
ref字段: ref表示列与索引的比较,表连接的匹配条件,表示哪些列或者常量被用于查询索引列上的值。
rows字段: rows表示估算的要扫描的行数,一般Mysql会根据统计表信息和索引的选用情况,估算出查找记录所要扫描的行数,注意这个数字是MySQL认为它要检查的行数,而不是结果集里的行数。
filtered列: 显示了通过条件过滤出的行数的百分比估计值。
Extra列: 该列包含MySQL解决查询的详细信息 Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。 Select tables optimized away MySQL根本没有遍历表或索引就返回数据了,表示已经优化到不能再优化了 Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。 range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。 Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行,说明查询就需要优化了。 Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。 Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果,说明查询就需要优化了。 Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。 Using sort_union(…), Using union(…), Using intersect(…):这些函数说明如何为index_merge联接类型合并索引扫描。 Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。