索引和索引优化
MysqlInnoDB使用B+树作为索引,如下图,是一个简化的B+数:
使用B+树作为索引有点非常明显的优点
1、B+树的数据都保存在叶子节点中,非叶子节点只保存指针,这样可以极大的减少数的阶数。如图如果每一阶可以存储1000个值,那么3阶树即可以存储1000*1000*1000=10亿个数据。而根节点一般是常驻内存的,所以查找10亿数据,2次磁盘IO即可完成。
2、B+数的所有叶子节点之间按顺序建立了链指针,也就是所有数据一定是按顺序存储的,并且每个叶子到根的距离相同,非常适合范围查找.
索引的几个概念
1、聚簇索引: 以主键创建的索引,叶子节点的数据是整行的全部数据,叶子节点也叫数据页。
2、普通索引:以非主键创建的索引,叶子节点数据是主键的值。
3、回表查询:从普通索引查找到主键值以后,再从聚簇索引根据该主键值查找相关数据的行为称为回表。
4、索引覆盖:普通索引可以有多列,如果要查询的数据全部在索引列中,则不会产生回表,称为索引覆盖.
优化建议
1、【重要】在表中建立索引: 建立索引时,优先考虑where和order by使用到的字段。业务上唯一的字段,即使是组合字段也要建唯一索引。
2、使用自增ID作为主键: 自增ID的是连续的,主键是聚簇索引,会连续的在磁盘中写入数据,减少了并不是业务逻辑的主键,业务逻辑不分页和移动数据的操作,IO速度最快。注意这是逻辑存储的主键推荐使用自增列作为主键,更不推荐与逻辑主键公用一个自增ID
3、索引不会包含有 null 值的列: 避免表字段运行为nul,只要列中包含有 nul 值都将不会被包含在索引中,复合索引中只要有一列含有 null 值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时建议不要让字段的默认值为 null。
4、【重要】使用短索引: 如果有一个 varchar (255) 的列,如果在前 10 个或 20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。
5、使用复合索引: 查询只使用一个索引,因此如果 where 子句中已经使用了索引的话,那么 order by 中的列是不会使用索引的。