索引存放的位置:

/usr/local/mysql文件夹中

  • InnoDB存储引擎: 将索引和数据存放在同一文件里(*.ibd)
  • MyISAM存储引擎: 索引和数据分开两个文件存储.索引*.MYI,数据*.MYD

索引分类

  1. 主键索引

    主键自带索引效果

  2. 普通索引

    为普通列创建的索引

  3. 唯一索引

    列中的数据是唯一的。比普通索引的性能要好

  4. 组合索引

    一次性为表中的多个字段一起创建索引

  5. 全文索引

    进行查询的时候,数据源可能来自于不同的字段或者不同的表(实际生产环境中,并不会使用MySQL提供的MyISAM存储引擎的全文索引功能来是实现全文查找。而是会使用第三方的搜索引擎中间件)

Explain执行计划

sql语句前面加explain,分析当前这条SQL语句的性能细节

后面加show warnings;可以查看内部优化器优化后的效果

select_type列

关闭 MySQL 对衍生表的合并优化:

set session optimizer_switch='derived_merge=off'; 
  • derived

    子查询只要在from后面,就会生成一张衍生表

  • subquery

    在select之后 from之前的子查询

  • primary

    最外部的select

  • simple

    不包含子查询的简单的查询

  • union

    使用union进行的联合查询的类型

table列

当前查询正在查哪张表

type列

type列可以直观的判断出当前的sql语句的性能。

type里的取值和性能的优劣顺序如下:

null > system > const > eq_ref > ref > range > index > all

对于SQL优化来说,要尽量保证type列的值是属于range及以上级别。

null

性能最好的,一般在使用了聚合函数操作索引列,结果直接从索引树获取即可,因此是性能最好。

system

很少见。直接和一条记录进行匹配。

const

使用主键索引或唯一索引和常量进行比较,这种性能非常好

eq_ref

在进行多表连接查询时。如果查询条件是使用了主键进行比较,那么当前查询类型是eq_ref

ref

如果查询条件是普通列索引,那么类型ref

range

使用索引进行范围查找

index

查询没有进行条件判断。但是所有的数据都可以直接从索引树上获取

all

没有走索引,进行了全表扫描

id列

id越大越先执行,如果id相同。从上到下执行

possible keys列

这一次的查询可能会用到的索引。也就是说mysql内部优化器会进行判断,如果这一次查询走索引的性能比全表扫描的性能要查,那么内部优化器就让此次查询进行全表扫描——这样的判断依据我们可以通过trace工具来查看

key列

实际该sql语句使用的索引

rows列

该sql语句可能要查询的数据条数

key_len列

键的长度,通过这一列可以让我们知道当前命中了联合索引中的哪几列。

计算规则:

- 字符串
1. char(n): n字节长度
2. varchar(n): 2字节存储字符串长度,如果是utf-8,则长度3n + 2

- 数值类型
1. tinyint: 1字节
2. smallint: 2字节
3. int: 4字节
4. bigint: 8字节

- 时间类型
1. date: 3字节
2. timestamp: 4字节
3. datetime: 8字节

如果字段允许为NULL,需要1字节记录是否为NULL
索引最大长度是768字节,当字符串过长时, mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引

extra列

extra列提供了额外的信息,是能够帮助我们判断当前sql的是否使用了覆盖索引、文件排序、使用了索引进行查询条件等等的信息。

Using index

使用了覆盖索引,所谓的覆盖索引,指的是当前查询的所有数据字段都是索引列,这就意味着可以直接从索引列中获取数据,而不需要进行查表。

using where

使用了普通索引列做查询条件

using index condition

查询结果没有使用覆盖索引,建议可以使用覆盖索引来优化

Using temporary

在非索引列上进行去重操作就需要使用一张临时表来实现,性能是非常差的。当前name列没有索引

Using filesort

使用文件排序: 会使用磁盘+内存的方式进行文件排序,会涉及到两个概念:单路排序、双路排序

Select tables optimized away

直接在索引列上进行聚合函数的操作,没有进行任何的表的操作

Trace工具

set session optimizer_trace="enabled=on", end_markers_in_json=on; -- 开启trace
 select * from dept; -- 执行查询
 SELECT * FROM information_schema.OPTIMIZER_TRACE; -- 获得trace的分析结果