性能分析

explain

  1. explain select * from table_name1
  2. where id = (select id from table_name2 where time_range = 3 );

使用 explain 分析 sql 语句后, 会生成一系列数据, 这些数据不同的字段有不同的含义.

explain 的执行结果

id

id 是 SQL 执行的顺序. SQL 会按照从大到小的顺序来执行的.

select_type

select 类型 含义
simple 不使用联合查询或子查询
primary 最外层的select
derived from 子句的子查询
union union 中的第二个或后面的 select 语句
union result union 的结果
dependent union union 中的第二个或后面的 select 语句
subquery 子查询中第一个 select
dependent subquery 子查询中的第一个 select,取决于外面的查询

table

有时候不是真实的表名字

type, 连接操作类型

这列很重要,显示了连接使用了哪种类型,有无使用索引。在各种类型的关联关系中,效率最高的是 System, 然后依次是const / eq_ref / ref /range/ index /all。一般而言,查询至少达到 range 级别,最好能 ref 级别,否则可能会出现性能问题。

  • system,表只有一行,system表
  • const
  • eq_ref
  • ref, 使用了不是唯一或主键的键或者是这些类型的部分是发生。
  • range,使用索引返回一个范围内的行。比如使用 >或 <
  • index。
  • all,全表扫描。

    possible_key

    possible_key, Mysql 在搜索数据记录是可以选用的各个索引名

    key

    key,Mysql 实际选用的索引

    ref

    ref,显示使用哪个列或常数与key一起从表中选择行

    rows

    rows,Mysql 认为它在找到正确结果之前必须扫描的记录数。

    extra

    extra ,附加信息。Using filesort,表明Mysql 需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排列键值和匹配条件的全部行的行指针来;Using temporary,Mysql 需要创建一个临时表来存储结果。一般看到这两个信息就表明需要优化了。

    重点分析的字段

    explain 执行的sql结果中, 重点分析 type 和 key.
    type 是看效率的级别, 如果是 range/index/all 就要考虑索引了;
    分析key, 主要是看添加的索引是否起作用了.

    性能优化

    添加索引

    创建表时主键使用 unsigned

    unsigned 属性就是将数字类型无符号化,INT的类型范围是-2 147 483 648 ~ 2 147 483 647, INT UNSIGNED的范围类型就是0 ~ 4 294 967 295。
    unsigned 的这个属性,可以使用在主键上。但是参考文章中却说不建议用unsigned 作为主键的属性,因为会有一些意想不到的错误,我动手试了一下,现在的 unsigned 类型 已经不能和 int 做运算了。

    用 join 代替子查询

    子查询
    select distinct(value) from tableName where name='minor_version' 
    and custins_id in (select id from tableName2 where parent_id=%s);
    
    join
    select distinct(value) from tableName as t1
    join tableName2 as t2 on t1.custins_id = t2.id
    where t1.name='minor_version' and t2.parent_id=%s