MySQL之SQL优化详解(二)

MySQL之SQL优化详解(二)

1. SQL的执行顺序

1.1 手写顺序

 

1.2 机读顺序

 

 

2. 七种join

 

3. 索引

3.1 索引初探

  • 是什么: 排好序的快速查找数据结构sql

  • 两个主要的索引结构: B+tree 索引和哈希索引。数据库

  • 如何建: 1. ALTER TABLE table_name ADD INDEX index_name (column_list); 2. CREATE INDEX index_name ON table_name (column_list);缓存

 

优势: 相似大学图书馆建书目索引,提升了检索效率,下降了数据库IO,同时还能够经过索引进行排序,下降数据排序的成本,下降了CPU的消耗数据结构

缺点: 虽然索引大大提升了查询速度,同时却会下降更新表的速度,如对表进行 insertupdatedelete,由于更新表时不只要保存数据,还要保存一下索引文件每次更新添加了索引列的字段。性能

 

3.2 索引分类

1.主键索引:主键是一种惟一性索引,但它必须指定为PRIMARY KEY,每一个表只能有一个主键优化

ALTER TABLE table_name ADD PRIMARY KEY (column_list)

2.惟一索引:索引列的全部值都只能出现一次,即必须 惟一,值能够为 空code

ALTER TABLE table_name ADD UNIQUE (column_list)

3.普通索引:基本的索引类型,值能够为空,没有惟一性的限制blog

ALTER TABLE table_name ADD INDEX index_name (column_list);

4.全文索引: 全文索引的索引类型为 FULLTEXT,全文索引只能建立在CHAR、VARCHAR、TEXT类型的字段上。查询数据量较大的字符串类型字段时,使用全文索引能够提升查询速度排序

ALTER TABLE table_name ADD FULLTEXT INDEX index_name(column_list);

 

3.3 建与不建

对于MySQL的索引建立,咱们常常有疑虑,那么何时该建何时不应建呢?

哪些状况须要建立索引

  1. 主键自动建立惟一索引

  2. 频繁做为查询条件的字段应该建立索引

  3. 查询中与其它表关联的字段,外键关系创建索引

  4. 查询中排序的字段,排序字段若经过索引去访问将大大提升排序速度

  5. 查询中统计或者分组字段

 

哪些状况不须要建索引

  1. 频繁更新的字段不适合建立索引
  2. where 条件用不到的字段不适合建立索引
  3. 注意,若是某个数据列包含许多重复的内容,为它创建索引就没有太大的实际效果

 

4. 性能分析Explain

Explain简称执行计划,使用Explain关键字能够模拟优化器执行SQL查询语句

用法:explain + SQL


 

1. id:select查询的序列号,包含一组数字,表示查询中执行select子句或操做表的顺序

① id 相同执行顺序由上至下

② id 不一样,若是是子查询,id的序号会递增,id值越大优先级越高,越先被执行

③ id相同不相同,不相同

注:id若是相同,能够认为是一组,从上往下顺序执行;在全部组中,id值越大,优先级越高,越先执行

 

2. select_type:查询的类型,主要是用于区分 普通查询、联合查询、子查询等的复杂查询

  • simple:简单的select 查询,查询中不包含子查询或者 union
  • primary:查询中若包含任何复杂的子部分,最外层查询则被标记为
  • subquery:在selectwhere列表中包含了子查询
  • derived:在from 列表中包含的子查询被标记为 derived(衍生)
  • union:若第二个select出如今以后,则被标记为 union(若union 包含from 子句的子查询中,外层select将被标记为:derived)
  • union result:从union 表获取结果的 select

 

3. table:显示这一行的数据是关于哪张表的

4. type:访问类型排列,显示查询使用了何种类型

从好到坏,system > const > eq_ref > ref > range > index > all

  • system:表只有一行记录(等于系统表),这是const 类型的特列,平时不会出现,这个也能够忽略不计
  • const:表示经过索引一次就找到了,const 用于比较 primary key或者unique索引
  • eq_ref:惟一性索引扫描,对于每一个索引键,表中只有一条记录与之匹配。常见于主键或惟一索引扫描
  • ref:非惟一性索引扫描,返回匹配某个单独值的全部行,本质上也是一种索引访问
  • range:只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪一个索引,通常就是在你的where语句中出现了 between、<、>、in等的查询
  • index:Full Index Scan,index与 all 区别为 index 类型只遍历索引树
  • all:Full Table Scan,将遍历全表以找到匹配的行

 

5. possible_key:显示可能应用在这张表的索引,一个或多个。(但不必定被实际应用)

6. key:实际使用的索引,若是为null,则没有使用索引。

查询中若使用了覆盖索引,则该索引与查询的select字段重叠

 

7. key_len:表示索引中使用的字节数

8. ref:显示索引的哪一列被使用,若是可能的话,是一个常数,哪些列或常量被用于查找索引列上的值

注:由key_len可知t1表的idx_col1_col2被充分使用,col1匹配t2表的col1col2匹配了一个常量,即 'ac'

 

9. rows:根据表统计信息及索引选用状况,大体估算出找到所需的记录所须要读取的行数

10. extra:包含不适合在其余列中显示但十分重要的额外信息

  • Using filesort (劣): mysql 会对数据使用一个外部的索引排序(文件排序),而不是照表内的索引顺序进行读取

 

  • Using temporary (劣):使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by

 

  • Using index (优):表示相应的select操做中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错!
  • Using where:代表使用了where 过滤
  • Using join buffer:代表使用了链接缓存
  • impossible where:where子句的值老是false,不能用来获取任何数据

 

  • select tables optimized away:select操做已经优化到不能再优化了(MySQL根本没有遍历表或索引就返回数据了
  • distinct:在select部分使用了distinc关键字

心法:

针对explain命令生成的执行计划,这里有一个查看心法。咱们能够先从查询类型type列开始查看,若是出现all关键字,后面的内容就均可以不用看了,表明全表扫描。再看key列,看是否使用了索引,null表明没有使用索引。而后看rows列,该列用来表示在SQL执行过程当中被扫描的行数,该数值越大,意味着须要扫描的行数越多,相应的耗时越长,最后看Extra列,在这列中要观察是否有Using filesort 或者Using temporary 这样的关键字出现,这些是很影响数据库性能的。

相关文章
相关标签/搜索