MYSQL逻辑架构介绍笔记

3 阅读1分钟

EXPLAIN

1. explain+sql:分析执行索引、扫描行数及优化空间等

2. show warnings:显示最后一个执行的语句所产生的错误、警告和提示等信息

存储引擎对比

特性

InnoDB

MyISAM

存储限制

64TB

256TB

事务

支持

不支持

锁粒度

行级锁

表级锁

外键

支持

不支持

支持的索引

B-Tree、全文索引(5.6开始支持,但不支持中文;5.7开始支持中文)、哈希索引(引擎自适应,不支持自定义)

B-Tree、全文索引

表行数统计

通过全表扫描,动态统计

已存储表行数

索引

选择关键字越小的那些列建索引,增加关键字的个数,增大m,减少树的高度

索引特性对比表

特性

B+TREE

HASH 索引

等值查询

支持

支持

范围查询

支持

不支持

使用部分索引键查询

支持

不支持

结果排序

支持

不支持

查询平均时间复杂度

O(log⁡m)

m为单节点关键字个数,n为总关键字个数,m越大,树高越低,查询复杂度越小

O(1)

等值查询高效,但键重复率高时性能退化

聚簇索引和非聚簇索引

聚簇索引(主键索引)

  1. 提升IO密集型应用性能(顺序读取)

  2. Row的移动不影响二级索引

  3. 如果主键值非自增(随机生成但有序),在插入记录时,可能造成记录移动或页分裂,影响性能

非聚簇索引

  1. 索引与数据分离,相对聚簇索引来说,占用空间小

  2. InnoDB二级索引,相对MyISAM会更大

  3. 使用InnoDB二级索引,select *涉及回表,需要检索两次B+Tree

  4. Row的移动,会影响MyISAM索引,没事不要移动数据

  5. 随机IO(SSD硬盘比较普遍,所以可忽略这部分影响)

索引设计理念

哪些列建议需要用到索引

WHERE、JOIN、GROUP BY、ORDER BY等语句用到的列

利用最左前缀

(A,B,C),按A排序,A相同再按B排序,以此类推

如何选择索引列的顺序

  1. 经常使用到的列优先

    1. 利用最左前缀,尽量复用已用索引
  2. 区分度大的列优先(对性别建索引,不如对姓名建索引)

    1. 区分度=列的所有不重复的值/所有值的个数,至少大于0.1(不大于0.1不建议建索引)

    2. 尽快排除掉更多的记录

  3. 宽度小的列优先(数据的大小,列的值越小,索引树的一个节点能存的key越多)

    1. 列宽度=列的数据类型

    2. 宽度越小,单节点的key值越多,索引树的高度越低,查询复杂度越低,性能越好

索引使用建议

type:连接的类型

  1. const、system:最多一个匹配行,使用主键或者unique索引(where id=xx)

  2. eq_ref:返回一行数据,通常在联接时出现,使用主键或者unique索引(联接的时候,右表采用的类型)

  3. ref:使用key的最左前缀,且key不是主键或unique键(线上最常见)

  4. range:索引范围扫描,对索引的扫描开始于某一点,返回匹配的行(线上保底)

  5. index:以索引的顺序进行全表扫描,优点是不用排序,缺点是还需要全表扫描

  6. all:全表扫描,必须避免

从上到下,是从建议到不建议的类型

range及以上是建议的类型,尽量避免index,杜绝使用all

extra:

using index:索引覆盖,查询只用到索引即可,无需回表,读取数据快

using where:在存储引擎返回记录后,再做过滤

using temporary:使用临时表,通常在GROUP BY、ORDER BY时出现(尽量不要出现,浪费存储的空间)

using filesort:用到非索引顺序的额外排序,额外的排序(可能是内存的排序,也可能是外排,即执行引擎层面去做的排序),取决于sortBuffer的大小

一旦使用了外排,性能就会出现比较大的退化——当ORDER BY未用到索引时会发生(一定要规避)

EXPLAIN的分析

  1. key是不能为NULL的,如果为NULL说明本次没有可用的索引,进行了全表的扫描

2. rows越小越好,虽然是估算

3. key_len,可理解为,使用了索引的哪些字段,长度加到一起

长度不需要具体去记,allow null使用时一定要慎重

不损失精确性的话,key_len越小越好;用不到的字段,移除

Force Index的用法

select * from xx force index xx where xx order by xx

问题记录

  1. using temporary:

    1. 暂存结果集,如果内存够用,就在内存,如果内存不够用,建一个临时表,外排

      另一个表关联,a和b关联,再和c关联,a和b关联的结果会创建一个临时表

    2. 在关联、排序结果的临时表

  2. using index condition:

    1. 查询结果的下推,联合索引(a、b、c),where a = xx and c = xx