MySQL SQL语句优化explain关键字

概述

在目前这个大数据,大流量时代,我们的网站不光流量大,数据量也会非常的巨大。在巨大的数据量中精确找出我们需要的数据,这个对我们数据库压力比较大。而我们在不考虑进行分库分表的操作时,进行SQL语句优化是一个很好的解决办法,下面介绍explain关键词分析SQL语句,及使用索引进行优化查询。

explain关键字使用

explain使用格式

	EXPLAIN SELECT
	*
	FROM
		SCORE
	WHERE
		CNO = '3-105'
	AND DEGREE > (
		SELECT
			DEGREE
		FROM
			SCORE
		WHERE
			SNO = 109
	)

查询结果

id select_type table type possible_keys key key_len ref rows extra
1 PRIMARY SCORE ALL null null null null 12 Using where
2 SUBQUERY SCORE ALL null null null null 12 Using where

explain表格各个属性分析

  • id:select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
  1. id相同时,执行顺序由上至下
  2. id不同时,如果是子查询,序号id会递增,id值越大优先级越高,越先被执行,在所有组中,id值越大优先级越高
  • select_type:查询类别,主要是区别普通查询,联合查询,子查询等复杂查询
  1. simple简单查询,不包含子查询
  2. primary:包含子查询,为最外层查询
  3. subquery:子查询
  4. derived:衍生表,虚拟表
  5. union:出现union关键字
  6. union select:在union结果中查询
  • table:查询的表名
  • type:执行计划包含的信息,显示查询使用了何种类型
type类型从最好到最差

system > const > eq_ref > ref > range >index > all
  1. system:表中只有一条记录(等于系统表),这是const类型的特例,平时不会出现,这个可以忽略不计。
  2. const:表示通过索引一次就找到了,const用于比较primary key或者union索引,因为只匹配一行数据,所以很快,如将主键置于where中。
  3. eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见主键或者唯一索引扫描
  4. ref:非唯一索引扫描,返回匹配条件的所有行。本质上也是一种索引,他返回所有匹配某个单独值得所有行,然而,他可能会找到多个符合条件得行,所以他应该属于查找和扫描得混合体。
  5. range:只检索给定范围的行,使用索引来选择行。key列显示使用了哪些索引,一般就在你的where语句中出现了between、<、>、in等查询,这种范围扫描比全表扫描要好,因为它只需要开始于索引的某一个点,而结束于某一个点,不用全表扫描。
  6. index:full index scan,indexall的区别为index类型只遍历索引树。这通常比all快,因为索引文件通常比数据文件小(也就是说虽然allindex都是全表扫描,但是index是从索引文件中进行扫描,all是通过硬盘中读取的)
  7. all:全表扫描
  • possible_keys:显示可能应用于查询的索引,一个或者多个。查询涉及到字段存在索引,则将索引列出,但不一定在查询中使用。
  • key:实际查询使用的索引。如果为null,则没有用到索引,若使用到了覆盖索引,则该索引只出现在key列表中。
  • key_len:显示索引中使用的字节数,可通过该列计算查询中使用到索引长度。在不损失精度下,长度越短越好。key_len显示的值为索引字段的最大长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出得。
  • ref:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或者常量被用于查找索引列上值。
  • rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录需要读取的行数
  • extra:不适合在其他列中显示,但又十分重要的信息
  1. using filesort:说明MySQL会对数据使用一个外部的索引排序,而不是按照表内索引进行读取。MySQL中无法利用索引完成排序操作称之为文件排序。如果出现这种情况,查询将会非常的慢
  2. using temporary:说明使用临时表保存中间结果,MySQL在对查询结果进行排序时,使用临时表。常见于排序order bygroup by。出现这种情况查询会非常慢。
  3. using index:表示相应的select操作中使用覆盖索引(covering index),避免访问数据行,效率很好!如果同时出现using where,表明索引被用来执行索引值查找;如果没有同时出现using where,表明索引用来读取非执行查找动作。
  4. using where:使用where关键字查找
  5. impossible where:子句的值总的false,不能用来获取任何元组

索引优化案例

  • 单表建立索引,查询的字段不要出现范围否则会出现索引失效的情况
  • 两个表连接查询建立索引,索引一般建在从表上,左连接,建立在右边;右连接,建立在左边。

索引失效情况(应该避免)

  • 全值匹配我最爱(查询条件完全符合索引顺序)
  • 最佳左前缀法则:如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左列开始并且 不跳过索引列(类别火车,火车头)
  • 不能在所有列上做任何操作(计算,函数,(自动or手动)类型转换),会导致索引失效,导致全表扫描
  • 存储引擎不能使用索引中范围条件右边的列
  • 尽量使用覆盖索引(只访问索引的查询),减少select *
  • 在使用不等于(!= 或者<>)的时候无法使用索引导致全表扫描
  • is null 或者is not null 也无法使用索引
  • like以通配符开头(’%abcd’),MySQL索引会失效会变成全表扫描
  • 字符串不加单引号索引也会失效
  • 少用or,用了它连接会导致索引失效

阿里巴巴规范

  • 推荐】:SQL性能优化的目标:至少要达到rang级别,要求是ref级别,如果可以是consts最好。
    说明consts单表中最多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。
    ref指的是使用普通的索引(normal index)
    rang对索引进行范围检索
    反例:explain表的结果,type=index,索引物理文件全扫描,速度非常慢,这个index级别比较range还低,与全表扫描是小巫见大巫
发布了27 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/justLym/article/details/105076001
今日推荐